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.dataflow.metadata.sqlflow.sharded.SqlflowShardedMetadataAnalyzer; 016import gudusoft.gsqlparser.dlineage.impl.powerquery.PowerQueryLineageResult; 017import gudusoft.gsqlparser.dlineage.impl.powerquery.TPowerQueryAnalyzer; 018import gudusoft.gsqlparser.dlineage.dataflow.model.*; 019import gudusoft.gsqlparser.dlineage.dataflow.model.Process; 020import gudusoft.gsqlparser.dlineage.dataflow.model.JoinRelationship.JoinClauseType; 021import gudusoft.gsqlparser.dlineage.dataflow.model.json.Coordinate; 022import gudusoft.gsqlparser.dlineage.dataflow.model.json.Dataflow; 023import gudusoft.gsqlparser.dlineage.dataflow.model.json.Error; 024import gudusoft.gsqlparser.dlineage.dataflow.model.xml.*; 025import gudusoft.gsqlparser.dlineage.dataflow.sqlenv.SQLEnvParser; 026import gudusoft.gsqlparser.dlineage.metadata.MetadataUtil; 027import gudusoft.gsqlparser.dlineage.metadata.Sqlflow; 028import gudusoft.gsqlparser.dlineage.util.*; 029import gudusoft.gsqlparser.nodes.TTable; 030import gudusoft.gsqlparser.nodes.*; 031import gudusoft.gsqlparser.nodes.couchbase.TObjectConstruct; 032import gudusoft.gsqlparser.nodes.couchbase.TPair; 033import gudusoft.gsqlparser.nodes.functions.TJsonObjectFunction; 034import gudusoft.gsqlparser.nodes.hive.THiveTransformClause; 035import gudusoft.gsqlparser.nodes.hive.THiveTransformClause.ETransformType; 036import gudusoft.gsqlparser.resolver2.ScopeBuildResult; 037import gudusoft.gsqlparser.resolver2.TSQLResolver2; 038import gudusoft.gsqlparser.sqlenv.*; 039import gudusoft.gsqlparser.sqlenv.parser.TJSONSQLEnvParser; 040import gudusoft.gsqlparser.stmt.*; 041import gudusoft.gsqlparser.stmt.db2.TDb2CallStmt; 042import gudusoft.gsqlparser.stmt.db2.TDb2ReturnStmt; 043import gudusoft.gsqlparser.stmt.db2.TDb2SqlVariableDeclaration; 044import gudusoft.gsqlparser.stmt.hive.THiveLoad; 045import gudusoft.gsqlparser.stmt.mssql.*; 046import gudusoft.gsqlparser.stmt.mysql.TLoadDataStmt; 047import gudusoft.gsqlparser.stmt.oracle.*; 048import gudusoft.gsqlparser.stmt.powerquery.TPowerQueryDocumentStmt; 049import gudusoft.gsqlparser.stmt.redshift.TRedshiftCopy; 050import gudusoft.gsqlparser.stmt.redshift.TRedshiftDeclare; 051import gudusoft.gsqlparser.stmt.snowflake.*; 052import gudusoft.gsqlparser.stmt.teradata.TTeradataCreateProcedure; 053import gudusoft.gsqlparser.util.*; 054import gudusoft.gsqlparser.util.json.JSON; 055 056import javax.script.ScriptEngine; 057import javax.script.ScriptEngineManager; 058import javax.script.ScriptException; 059import java.io.*; 060import java.util.zip.GZIPInputStream; 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 final List<DynamicSqlSite> dynamicSqlSites = new ArrayList<DynamicSqlSite>(); 093 private IndexedLinkedHashMap<String, List<SqlInfo>> sqlInfoMap = new IndexedLinkedHashMap<String, List<SqlInfo>>(); 094 private TSQLEnv sqlenv = null; 095 private ModelBindingManager modelManager = new ModelBindingManager(); 096 private ModelFactory modelFactory = new ModelFactory(modelManager); 097 private PipelinedFunctionAnalyzer pipelinedAnalyzer; 098 private List<Long> tableIds = new ArrayList<Long>(); 099 private TTableList hiveFromTables; 100 private dataflow dataflow; 101 private String dataflowString; 102 private Option option = new Option(); 103 104 { 105 modelManager.TABLE_COLUMN_ID = option.getStartId(); 106 modelManager.RELATION_ID = option.getStartId(); 107 ModelBindingManager.set(modelManager); 108 ModelBindingManager.setGlobalStmtStack(stmtStack); 109 ModelBindingManager.setGlobalOption(option); 110 ModelBindingManager.setGlobalSqlInfo(sqlInfoMap); 111 } 112 113 private void initPipelinedFunctionAnalyzer() { 114 // Only initialize pipelinedAnalyzer for Oracle 115 if (option.getVendor() == EDbVendor.dbvoracle) 116 { 117 pipelinedAnalyzer = new PipelinedFunctionAnalyzer(modelManager, modelFactory, option); 118 } 119 else{ 120 pipelinedAnalyzer = null; 121 } 122 } 123 124 public DataFlowAnalyzer(String sqlContent, Option option) { 125 SqlInfo[] sqlInfos = new SqlInfo[1]; 126 SqlInfo info = new SqlInfo(); 127 info.setSql(sqlContent); 128 info.setOriginIndex(0); 129 sqlInfos[0] = info; 130 this.option = option; 131 ModelBindingManager.setGlobalOption(this.option); 132 this.sqlInfos = convertSQL(option.getVendor(), JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]); 133 } 134 135 public DataFlowAnalyzer(String sqlContent, EDbVendor dbVendor, boolean simpleOutput, String defaultServer, 136 String defaultDatabase, String defaltSchema) { 137 SqlInfo[] sqlInfos = new SqlInfo[1]; 138 SqlInfo info = new SqlInfo(); 139 info.setSql(sqlContent); 140 info.setOriginIndex(0); 141 sqlInfos[0] = info; 142 option.setVendor(dbVendor); 143 option.setSimpleOutput(simpleOutput); 144 option.setDefaultServer(defaultServer); 145 option.setDefaultDatabase(defaultDatabase); 146 option.setDefaultSchema(defaltSchema); 147 this.sqlInfos = convertSQL(dbVendor, JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]); 148 } 149 150 public DataFlowAnalyzer(String sqlContent, EDbVendor dbVendor, boolean simpleOutput) { 151 SqlInfo[] sqlInfos = new SqlInfo[1]; 152 SqlInfo info = new SqlInfo(); 153 info.setSql(sqlContent); 154 info.setOriginIndex(0); 155 sqlInfos[0] = info; 156 option.setVendor(dbVendor); 157 option.setSimpleOutput(simpleOutput); 158 this.sqlInfos = convertSQL(dbVendor, JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]); 159 } 160 161 public DataFlowAnalyzer(String[] sqlContents, Option option) { 162 SqlInfo[] sqlInfos = new SqlInfo[sqlContents.length]; 163 for (int i = 0; i < sqlContents.length; i++) { 164 SqlInfo info = new SqlInfo(); 165 info.setSql(sqlContents[i]); 166 info.setOriginIndex(0); 167 sqlInfos[i] = info; 168 } 169 this.option = option; 170 ModelBindingManager.setGlobalOption(this.option); 171 this.sqlInfos = convertSQL(option.getVendor(), JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]); 172 } 173 174 public DataFlowAnalyzer(String[] sqlContents, EDbVendor dbVendor, boolean simpleOutput, String defaultServer, 175 String defaultDatabase, String defaltSchema) { 176 SqlInfo[] sqlInfos = new SqlInfo[sqlContents.length]; 177 for (int i = 0; i < sqlContents.length; i++) { 178 SqlInfo info = new SqlInfo(); 179 info.setSql(sqlContents[i]); 180 info.setOriginIndex(0); 181 sqlInfos[i] = info; 182 } 183 option.setVendor(dbVendor); 184 option.setSimpleOutput(simpleOutput); 185 option.setDefaultServer(defaultServer); 186 option.setDefaultDatabase(defaultDatabase); 187 option.setDefaultSchema(defaltSchema); 188 this.sqlInfos = convertSQL(dbVendor, JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]); 189 } 190 191 public DataFlowAnalyzer(String[] sqlContents, EDbVendor dbVendor, boolean simpleOutput) { 192 SqlInfo[] sqlInfos = new SqlInfo[sqlContents.length]; 193 for (int i = 0; i < sqlContents.length; i++) { 194 SqlInfo info = new SqlInfo(); 195 info.setSql(sqlContents[i]); 196 info.setOriginIndex(0); 197 sqlInfos[i] = info; 198 } 199 option.setVendor(dbVendor); 200 option.setSimpleOutput(simpleOutput); 201 this.sqlInfos = convertSQL(dbVendor, JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]); 202 } 203 204 public DataFlowAnalyzer(SqlInfo[] sqlInfos, Option option) { 205 this.sqlInfos = sqlInfos; 206 this.option = option; 207 ModelBindingManager.setGlobalOption(this.option); 208 } 209 210 public DataFlowAnalyzer(SqlInfo[] sqlInfos, EDbVendor dbVendor, boolean simpleOutput) { 211 this.sqlInfos = sqlInfos; 212 option.setVendor(dbVendor); 213 option.setSimpleOutput(simpleOutput); 214 } 215 216 public DataFlowAnalyzer(File[] sqlFiles, Option option) { 217 SqlInfo[] sqlInfos = new SqlInfo[sqlFiles.length]; 218 for (int i = 0; i < sqlFiles.length; i++) { 219 SqlInfo info = new SqlInfo(); 220 info.setSql(SQLUtil.getFileContent(sqlFiles[i])); 221 info.setFileName(sqlFiles[i].getName()); 222 info.setFilePath(sqlFiles[i].getAbsolutePath()); 223 info.setOriginIndex(0); 224 sqlInfos[i] = info; 225 } 226 this.sqlInfos = sqlInfos; 227 this.option = option; 228 ModelBindingManager.setGlobalOption(this.option); 229 } 230 231 public DataFlowAnalyzer(File[] sqlFiles, EDbVendor dbVendor, boolean simpleOutput) { 232 SqlInfo[] sqlInfos = new SqlInfo[sqlFiles.length]; 233 for (int i = 0; i < sqlFiles.length; i++) { 234 SqlInfo info = new SqlInfo(); 235 info.setSql(SQLUtil.getFileContent(sqlFiles[i])); 236 info.setFileName(sqlFiles[i].getName()); 237 info.setFilePath(sqlFiles[i].getAbsolutePath()); 238 info.setOriginIndex(0); 239 sqlInfos[i] = info; 240 } 241 this.sqlInfos = sqlInfos; 242 option.setVendor(dbVendor); 243 option.setSimpleOutput(simpleOutput); 244 } 245 246 public DataFlowAnalyzer(File sqlFile, Option option) { 247 File[] children = SQLUtil.listFiles(sqlFile); 248 SqlInfo[] sqlInfos = new SqlInfo[children.length]; 249 for (int i = 0; i < children.length; i++) { 250 SqlInfo info = new SqlInfo(); 251 info.setSql(SQLUtil.getFileContent(children[i])); 252 info.setFileName(children[i].getName()); 253 info.setFilePath(children[i].getAbsolutePath()); 254 info.setOriginIndex(0); 255 sqlInfos[i] = info; 256 } 257 this.sqlInfos = sqlInfos; 258 this.option = option; 259 ModelBindingManager.setGlobalOption(this.option); 260 } 261 262 public DataFlowAnalyzer(File sqlFile, EDbVendor dbVendor, boolean simpleOutput) { 263 File[] children = SQLUtil.listFiles(sqlFile); 264 List<SqlInfo> sqlInfos = new ArrayList<>(); 265 for (int i = 0; i < children.length; i++) { 266 SqlInfo info = new SqlInfo(); 267 info.setSql(SQLUtil.getFileContent(children[i])); 268 if(children[i].getName().toLowerCase().endsWith(".csv")){ 269 if(!MetadataReader.isMetadata(info.getSql())){ 270 continue; 271 } 272 } 273 else if(children[i].getName().toLowerCase().endsWith(".json")){ 274 if (!(MetadataReader.isGrabit(info.getSql()) || MetadataReader.isSqlflow(info.getSql()) || MetadataReader.isSqlflowSharded(info.getSql()))){ 275 continue; 276 } 277 } 278 info.setFileName(children[i].getName()); 279 info.setFilePath(children[i].getAbsolutePath()); 280 info.setOriginIndex(0); 281 sqlInfos.add(info); 282 } 283 this.sqlInfos = sqlInfos.toArray(new SqlInfo[0]); 284 option.setVendor(dbVendor); 285 option.setSimpleOutput(simpleOutput); 286 } 287 288 public boolean isIgnoreRecordSet() { 289 return option.isIgnoreRecordSet(); 290 } 291 292 public void setIgnoreRecordSet(boolean ignoreRecordSet) { 293 option.setIgnoreRecordSet(ignoreRecordSet); 294 } 295 296 public boolean isSimpleShowTopSelectResultSet() { 297 return option.isSimpleShowTopSelectResultSet(); 298 } 299 300 public void setSimpleShowTopSelectResultSet(boolean simpleShowTopSelectResultSet) { 301 option.setSimpleShowTopSelectResultSet(simpleShowTopSelectResultSet); 302 } 303 304 public boolean isSimpleShowFunction() { 305 return option.isSimpleShowFunction(); 306 } 307 308 public void setSimpleShowFunction(boolean simpleShowFunction) { 309 option.setSimpleShowFunction(simpleShowFunction); 310 } 311 312 public boolean isShowJoin() { 313 return option.isShowJoin(); 314 } 315 316 public void setShowJoin(boolean showJoin) { 317 option.setShowJoin(showJoin); 318 } 319 320 public void setShowCallRelation(boolean showCallRelation) { 321 option.setShowCallRelation(showCallRelation); 322 } 323 324 public boolean isShowCallRelation() { 325 return option.isShowCallRelation(); 326 } 327 328 public boolean isShowImplicitSchema() { 329 return option.isShowImplicitSchema(); 330 } 331 332 public void setShowImplicitSchema(boolean showImplicitSchema) { 333 option.setShowImplicitSchema(showImplicitSchema); 334 } 335 336 public boolean isShowConstantTable() { 337 return option.isShowConstantTable(); 338 } 339 340 public void setShowConstantTable(boolean showConstantTable) { 341 option.setShowConstantTable(showConstantTable); 342 } 343 344 public boolean isShowCountTableColumn() { 345 return option.isShowCountTableColumn(); 346 } 347 348 public void setShowCountTableColumn(boolean showCountTableColumn) { 349 option.setShowCountTableColumn(showCountTableColumn); 350 } 351 352 public boolean isTransform() { 353 return option.isTransform(); 354 } 355 356 public void setTransform(boolean transform) { 357 option.setTransform(transform); 358 if (option.isTransformCoordinate()) { 359 option.setTransform(true); 360 } 361 } 362 363 public boolean isTransformCoordinate() { 364 return option.isTransformCoordinate(); 365 } 366 367 public void setTransformCoordinate(boolean transformCoordinate) { 368 option.setTransformCoordinate(transformCoordinate); 369 if (transformCoordinate) { 370 option.setTransform(true); 371 } 372 } 373 374 public boolean isLinkOrphanColumnToFirstTable() { 375 return option.isLinkOrphanColumnToFirstTable(); 376 } 377 378 public void setLinkOrphanColumnToFirstTable(boolean linkOrphanColumnToFirstTable) { 379 option.setLinkOrphanColumnToFirstTable(linkOrphanColumnToFirstTable); 380 } 381 382 public boolean isIgnoreTemporaryTable() { 383 return option.isIgnoreTemporaryTable(); 384 } 385 386 public void setIgnoreTemporaryTable(boolean ignoreTemporaryTable) { 387 option.setIgnoreTemporaryTable(ignoreTemporaryTable); 388 } 389 390 public boolean isIgnoreCoordinate() { 391 return option.isIgnoreCoordinate(); 392 } 393 394 public void setIgnoreCoordinate(boolean ignoreCoordinate) { 395 option.setIgnoreCoordinate(ignoreCoordinate); 396 } 397 398 public void setHandleListener(DataFlowHandleListener listener) { 399 option.setHandleListener(listener); 400 } 401 402 public void setSqlEnv(TSQLEnv sqlenv) { 403 this.sqlenv = sqlenv; 404 } 405 406 public void setOption(Option option) { 407 this.option = option; 408 ModelBindingManager.setGlobalOption(this.option); 409 } 410 411 public Option getOption() { 412 return option; 413 } 414 415 public synchronized String chechSyntax() { 416 StringBuilder builder = new StringBuilder(); 417 if (sqlInfos != null) { 418 for (SqlInfo sqlInfo : sqlInfos) { 419 String content = sqlInfo.getSql(); 420 if (content != null && content.indexOf("<dlineage") != -1) { 421 try { 422 XML2Model.loadXML(dataflow.class, content); 423 continue; 424 } catch (Exception e) { 425 builder.append("Parsing dataflow ").append("occurs errors.\n").append(e.getMessage()) 426 .append("\n"); 427 } 428 } 429 if (content != null && content.trim().startsWith("{")) { 430 Map queryObject = (Map) JSON.parseObject(content); 431 content = (String) queryObject.get("sourceCode"); 432 } 433 if (MetadataReader.isMetadata(content)) { 434 continue; 435 } 436 TGSqlParser sqlparser = new TGSqlParser(option.getVendor()); 437 sqlparser.sqltext = content; 438 int result = sqlparser.parse(); 439 if (result != 0) { 440 builder.append("Parsing sql ").append("occurs errors.\n").append(sqlparser.getErrormessage()) 441 .append("\n"); 442 } 443 } 444 } 445 return builder.toString(); 446 } 447 448 public synchronized String generateDataFlow(boolean withExtraInfo) { 449 if (ModelBindingManager.get() == null) { 450 ModelBindingManager.set(modelManager); 451 } 452 453 initPipelinedFunctionAnalyzer(); 454 455 dataflow = analyzeSqlScript(); 456 457 if (dataflow != null && !withExtraInfo && dataflow.getResultsets() != null) { 458 for (table t : dataflow.getResultsets()) { 459 t.setIsTarget(null); 460 if (t.getColumns() != null) { 461 for (column t1 : t.getColumns()) { 462 t1.setIsFunction(null); 463 } 464 } 465 } 466 } 467 468 if(dataflow!=null && dataflow.getRelationships()!=null && option.getFilterRelationTypes()!=null && !option.getFilterRelationTypes().isEmpty()) { 469 List<relationship> relationships = new ArrayList<relationship>(); 470 for(relationship relationship: dataflow.getRelationships()) { 471 if(option.getFilterRelationTypes().contains(relationship.getType())) { 472 relationships.add(relationship); 473 } 474 } 475 dataflow.setRelationships(relationships); 476 } 477 478 if (option.getHandleListener() != null) { 479 option.getHandleListener().endAnalyze(dataflow); 480 } 481 482 if (option.isOutput()) { 483 if (option.getHandleListener() != null) { 484 option.getHandleListener().startOutputDataFlowXML(); 485 } 486 if (dataflow != null) { 487 if (option.isTextFormat()) { 488 dataflowString = getTextOutput(dataflow); 489 } else { 490 try { 491 dataflowString = XML2Model.saveXML(dataflow); 492 }catch (Exception e){ 493 logger.error("Output dataflow to xml failed.", e); 494 dataflowString = null; 495 } 496 } 497 } 498 if (option.getHandleListener() != null) { 499 option.getHandleListener().endOutputDataFlowXML(dataflowString == null ? 0 : dataflowString.length()); 500 } 501 } 502 503 return dataflowString; 504 } 505 506 private dataflow removeDuplicateColumns(dataflow dataflow) { 507 List<table> tables = new ArrayList<table>(); 508 if (dataflow.getTables() != null) { 509 tables.addAll(dataflow.getTables()); 510 } 511 if (dataflow.getViews() != null) { 512 tables.addAll(dataflow.getViews()); 513 } 514 if (dataflow.getStages() != null) { 515 tables.addAll(dataflow.getStages()); 516 } 517 if (dataflow.getDatasources() != null) { 518 tables.addAll(dataflow.getDatasources()); 519 } 520 if (dataflow.getStreams() != null) { 521 tables.addAll(dataflow.getStreams()); 522 } 523 if (dataflow.getPaths() != null) { 524 tables.addAll(dataflow.getPaths()); 525 } 526 if (dataflow.getVariables() != null) { 527 tables.addAll(dataflow.getVariables()); 528 } 529 if (dataflow.getResultsets() != null) { 530 tables.addAll(dataflow.getResultsets()); 531 } 532 for (table table : tables) { 533 if (table.getColumns() == null) { 534 continue; 535 } 536 Set<String> columnIds = new HashSet<String>(); 537 Iterator<column> iter = table.getColumns().iterator(); 538 while(iter.hasNext()) { 539 column column = iter.next(); 540 String id = column.getId(); 541 if (columnIds.contains(id)) { 542 iter.remove(); 543 } else { 544 columnIds.add(id); 545 } 546 } 547 } 548 return dataflow; 549 } 550 551 public synchronized String generateDataFlow() { 552 return generateDataFlow(false); 553 } 554 555 public synchronized String generateSqlInfos() { 556 return JSON.toJSONString(sqlInfoMap); 557 } 558 559 public Map<String, List<SqlInfo>> getSqlInfos() { 560 return sqlInfoMap; 561 } 562 563 public Map getHashSQLMap() { 564 return modelManager.getHashSQLMap(); 565 } 566 567 public Map getDynamicSQLMap() { 568 return modelManager.getDynamicSQLMap(); 569 } 570 571 /** 572 * @deprecated please use SqlInfoHelper.getSelectedDbObjectInfo 573 */ 574 public DbObjectPosition getSelectedDbObjectInfo(Coordinate start, Coordinate end) { 575 if (start == null || end == null) { 576 throw new IllegalArgumentException("Coordinate can't be null."); 577 } 578 579 String hashCode = start.getHashCode(); 580 581 if (hashCode == null) { 582 throw new IllegalArgumentException("Coordinate hashcode can't be null."); 583 } 584 585 int dbObjectStartLine = (int) start.getX() - 1; 586 int dbObjectStarColumn = (int) start.getY() - 1; 587 int dbObjectEndLine = (int) end.getX() - 1; 588 int dbObjectEndColumn = (int) end.getY() - 1; 589 List<SqlInfo> sqlInfoList; 590 if (hashCode.matches("\\d+")) { 591 sqlInfoList = sqlInfoMap.getValueAtIndex(Integer.valueOf(hashCode)); 592 } else { 593 sqlInfoList = sqlInfoMap.get(hashCode); 594 } 595 for (int j = 0; j < sqlInfoList.size(); j++) { 596 SqlInfo sqlInfo = sqlInfoList.get(j); 597 int startLine = sqlInfo.getLineStart(); 598 int endLine = sqlInfo.getLineEnd(); 599 if (dbObjectStartLine >= startLine && dbObjectStartLine <= endLine) { 600 DbObjectPosition position = new DbObjectPosition(); 601 position.setFile(sqlInfo.getFileName()); 602 position.setFilePath(sqlInfo.getFilePath()); 603 position.setSql(sqlInfo.getSql()); 604 position.setIndex(sqlInfo.getOriginIndex()); 605 List<Pair<Integer, Integer>> positions = position.getPositions(); 606 positions.add(new Pair<Integer, Integer>( 607 dbObjectStartLine - startLine + sqlInfo.getOriginLineStart() + 1, dbObjectStarColumn + 1)); 608 positions.add(new Pair<Integer, Integer>(dbObjectEndLine - startLine + sqlInfo.getOriginLineStart() + 1, 609 dbObjectEndColumn + 1)); 610 return position; 611 } 612 } 613 return null; 614 } 615 616 public static dataflow mergeTables(dataflow dataflow, Long startId) { 617 return mergeTables(dataflow, startId, new Option()); 618 } 619 620 public static dataflow mergeTables(dataflow dataflow, Long startId, Option option) { 621 List<table> tableCopy = new ArrayList<table>(); 622 List<table> viewCopy = new ArrayList<table>(); 623 List<table> databaseCopy = new ArrayList<table>(); 624 List<table> schemaCopy = new ArrayList<table>(); 625 List<table> stageCopy = new ArrayList<table>(); 626 List<table> dataSourceCopy = new ArrayList<table>(); 627 List<table> streamCopy = new ArrayList<table>(); 628 List<table> fileCopy = new ArrayList<table>(); 629 List<table> variableCopy = new ArrayList<table>(); 630 List<table> cursorCopy = new ArrayList<table>(); 631 List<table> resultSetCopy = new ArrayList<table>(); 632 if (dataflow.getTables() != null) { 633 tableCopy.addAll(dataflow.getTables()); 634 } 635 dataflow.setTables(tableCopy); 636 if (dataflow.getViews() != null) { 637 viewCopy.addAll(dataflow.getViews()); 638 } 639 dataflow.setViews(viewCopy); 640 if (dataflow.getDatabases() != null) { 641 databaseCopy.addAll(dataflow.getDatabases()); 642 } 643 dataflow.setDatabases(databaseCopy); 644 if (dataflow.getSchemas() != null) { 645 schemaCopy.addAll(dataflow.getSchemas()); 646 } 647 dataflow.setSchemas(schemaCopy); 648 if (dataflow.getStages() != null) { 649 stageCopy.addAll(dataflow.getStages()); 650 } 651 dataflow.setStages(stageCopy); 652 if (dataflow.getDatasources() != null) { 653 dataSourceCopy.addAll(dataflow.getDatasources()); 654 } 655 dataflow.setDatasources(dataSourceCopy); 656 if (dataflow.getStreams() != null) { 657 streamCopy.addAll(dataflow.getStreams()); 658 } 659 dataflow.setStreams(streamCopy); 660 if (dataflow.getPaths() != null) { 661 fileCopy.addAll(dataflow.getPaths()); 662 } 663 dataflow.setPaths(fileCopy); 664 if (dataflow.getVariables() != null) { 665 variableCopy.addAll(dataflow.getVariables()); 666 } 667 dataflow.setVariables(variableCopy); 668 if (dataflow.getResultsets() != null) { 669 resultSetCopy.addAll(dataflow.getResultsets()); 670 } 671 dataflow.setResultsets(resultSetCopy); 672 673 Map<String, List<table>> tableMap = new HashMap<String, List<table>>(); 674 Map<String, String> tableTypeMap = new HashMap<String, String>(); 675 Map<String, TMssqlCreateType> mssqlTypeMap = new HashMap<String, TMssqlCreateType>(); 676 Map<String, String> tableIdMap = new HashMap<String, String>(); 677 678 Map<String, List<column>> columnMap = new HashMap<String, List<column>>(); 679 Map<String, Set<String>> tableColumnMap = new HashMap<String, Set<String>>(); 680 Map<String, String> columnIdMap = new HashMap<String, String>(); 681 Map<String, column> columnMergeIdMap = new HashMap<String, column>(); 682 683 List<table> tables = new ArrayList<table>(); 684 tables.addAll(dataflow.getTables()); 685 tables.addAll(dataflow.getViews()); 686 tables.addAll(dataflow.getDatabases()); 687 tables.addAll(dataflow.getSchemas()); 688 tables.addAll(dataflow.getStages()); 689 tables.addAll(dataflow.getDatasources()); 690 tables.addAll(dataflow.getStreams()); 691 tables.addAll(dataflow.getPaths()); 692 tables.addAll(dataflow.getResultsets()); 693 tables.addAll(dataflow.getVariables()); 694 695 Set<String> columnIds = new HashSet<String>(); 696 697 for (table table : tables) { 698 String qualifiedTableName = DlineageUtil.getQualifiedTableName(table); 699 String tableFullName = DlineageUtil.getIdentifierNormalTableName(qualifiedTableName); 700 if ("variable".endsWith(table.getType()) && !SQLUtil.isEmpty(table.getParent())) { 701 tableFullName = table.getParent() + "." + tableFullName; 702 } 703 704 if (!tableMap.containsKey(tableFullName)) { 705 tableMap.put(tableFullName, new ArrayList<table>()); 706 } 707 708 tableMap.get(tableFullName).add(table); 709 710 if (!tableTypeMap.containsKey(tableFullName)) { 711 tableTypeMap.put(tableFullName, table.getType()); 712 } else if ("view".equals(table.getSubType())) { 713 tableTypeMap.put(tableFullName, table.getType()); 714 } else if ("database".equals(table.getSubType())) { 715 tableTypeMap.put(tableFullName, table.getType()); 716 } else if ("schema".equals(table.getSubType())) { 717 tableTypeMap.put(tableFullName, table.getType()); 718 } else if ("stage".equals(table.getSubType())) { 719 tableTypeMap.put(tableFullName, table.getType()); 720 } else if ("sequence".equals(table.getSubType())) { 721 tableTypeMap.put(tableFullName, table.getType()); 722 } else if ("datasource".equals(table.getSubType())) { 723 tableTypeMap.put(tableFullName, table.getType()); 724 } else if ("stream".equals(table.getSubType())) { 725 tableTypeMap.put(tableFullName, table.getType()); 726 } else if ("file".equals(table.getSubType())) { 727 tableTypeMap.put(tableFullName, table.getType()); 728 } else if ("table".equals(tableTypeMap.get(tableFullName))) { 729 tableTypeMap.put(tableFullName, table.getType()); 730 } else if ("variable".equals(tableTypeMap.get(tableFullName))) { 731 tableTypeMap.put(tableFullName, table.getType()); 732 } 733 734 if (table.getColumns() != null) { 735 if (!tableColumnMap.containsKey(tableFullName)) { 736 tableColumnMap.put(tableFullName, new LinkedHashSet<String>()); 737 } 738 for (column column : table.getColumns()) { 739 String columnFullName = tableFullName + "." 740 + (column.getQualifiedTable() != null 741 ? (DlineageUtil.getIdentifierNormalTableName(column.getQualifiedTable()) + ".") 742 : "") 743 + ("false".equals(table.getIsTarget()) ? DlineageUtil.normalizeColumnName(column.getName()) 744 : DlineageUtil.getIdentifierNormalColumnName(column.getName())); 745 746 if (!columnMap.containsKey(columnFullName)) { 747 columnMap.put(columnFullName, new ArrayList<column>()); 748 tableColumnMap.get(tableFullName).add(columnFullName); 749 } 750 751 columnMap.get(columnFullName).add(column); 752 columnIds.add(column.getId()); 753 } 754 } 755 } 756 757 Set<String> relationParentIds = new HashSet<String>(); 758 if (dataflow.getRelationships() != null) { 759 for (relationship rel : dataflow.getRelationships()) { 760 if (rel.getSources() != null) { 761 for (sourceColumn src : rel.getSources()) { 762 if (src.getParent_id() != null) { 763 relationParentIds.add(src.getParent_id()); 764 } 765 } 766 } 767 if (rel.getTarget() != null) { 768 if (rel.getTarget().getParent_id() != null) { 769 relationParentIds.add(rel.getTarget().getParent_id()); 770 } 771 } 772 } 773 } 774 775 Iterator<String> tableNameIter = tableMap.keySet().iterator(); 776 while (tableNameIter.hasNext()) { 777 String tableName = tableNameIter.next(); 778 List<table> tableList = tableMap.get(tableName); 779 table table; 780 if (tableList.size() > 1) { 781 table standardTable = tableList.get(0); 782 // Function允许重名,不做合并处理 783 if (standardTable.isFunction()) { 784 continue; 785 } 786 787 // Variable允许重名,不做合并处理 788 if (standardTable.isVariable()) { 789 continue; 790 } 791 792 // 临时表不做合并处理 793 if(SQLUtil.isTempTable(standardTable)) { 794 continue; 795 } 796 797 String type = tableTypeMap.get(tableName); 798 table = new table(); 799 table.setId(String.valueOf(++startId)); 800 table.setServer(standardTable.getServer()); 801 table.setDatabase(standardTable.getDatabase()); 802 table.setSchema(standardTable.getSchema()); 803 table.setName(standardTable.getName()); 804 table.setDisplayName(standardTable.getDisplayName()); 805 table.setParent(standardTable.getParent()); 806 table.setMore(standardTable.getMore()); 807 if (standardTable.getCandidateTables() != null && !standardTable.getCandidateTables().isEmpty()) { 808 table.setCandidateTables(new ArrayList<String>(standardTable.getCandidateTables())); 809 } 810 table.setColumns(new ArrayList<column>()); 811 String subType = null; 812 for(table item: tableList){ 813 if (item.getSubType() != null) { 814 subType = item.getSubType(); 815 break; 816 } 817 } 818 if (subType != null) { 819 table.setSubType(subType); 820 } else { 821 table.setSubType(standardTable.getSubType()); 822 } 823 Set<String> processIds = new LinkedHashSet<String>(); 824 for (int k = 0; k < tableList.size(); k++) { 825 if (tableList.get(k).getProcessIds() != null) { 826 processIds.addAll(tableList.get(k).getProcessIds()); 827 } 828 } 829 if (!processIds.isEmpty()) { 830 table.setProcessIds(new ArrayList<String>(processIds)); 831 } 832 Set<String> alias = new LinkedHashSet<String>(); 833 for (int k = 0; k < tableList.size(); k++) { 834 if (tableList.get(k).getAlias() != null) { 835 alias.addAll(Arrays.asList(tableList.get(k).getAlias().split("\\s*,\\s*"))); 836 } 837 } 838 if (!alias.isEmpty()) { 839 String aliasString = Arrays.toString(alias.toArray(new String[0])); 840 table.setAlias(aliasString.substring(1, aliasString.length() - 1)); 841 } 842 table.setType(type); 843 for (table item : tableList) { 844 if (!SQLUtil.isEmpty(table.getCoordinate()) && !SQLUtil.isEmpty(item.getCoordinate())) { 845 if (table.getCoordinate().indexOf(item.getCoordinate()) == -1) { 846 table.appendCoordinate(item.getCoordinate()); 847 } 848 } else if (!SQLUtil.isEmpty(item.getCoordinate())) { 849 table.setCoordinate(item.getCoordinate()); 850 } 851 852 if (item.getStarStmt() != null) { 853 table.setStarStmt(item.getStarStmt()); 854 } 855 856 tableIdMap.put(item.getId(), table.getId()); 857 858 if (item.isView()) { 859 dataflow.getViews().remove(item); 860 } else if (item.isDatabaseType()) { 861 dataflow.getDatabases().remove(item); 862 } else if (item.isSchemaType()) { 863 dataflow.getSchemas().remove(item); 864 } else if (item.isStage()) { 865 dataflow.getStages().remove(item); 866 } else if (item.isDataSource()) { 867 dataflow.getDatasources().remove(item); 868 } else if (item.isStream()) { 869 dataflow.getStreams().remove(item); 870 } else if (item.isFile()) { 871 dataflow.getPaths().remove(item); 872 } else if (item.isVariable()) { 873 dataflow.getVariables().remove(item); 874 } else if (item.isTable()) { 875 dataflow.getTables().remove(item); 876 } else if (item.isResultSet()) { 877 dataflow.getResultsets().remove(item); 878 } 879 } 880 881 if (table.isView()) { 882 dataflow.getViews().add(table); 883 } else if (table.isDatabaseType()) { 884 dataflow.getDatabases().add(table); 885 } else if (table.isSchemaType()) { 886 dataflow.getSchemas().add(table); 887 } else if (table.isStage()) { 888 dataflow.getStages().add(table); 889 } else if (table.isDataSource()) { 890 dataflow.getDatasources().add(table); 891 } else if (table.isStream()) { 892 dataflow.getStreams().add(table); 893 } else if (table.isFile()) { 894 dataflow.getPaths().add(table); 895 } else if (table.isVariable()) { 896 dataflow.getVariables().add(table); 897 } else if (table.isResultSet()) { 898 dataflow.getResultsets().add(table); 899 } else { 900 dataflow.getTables().add(table); 901 } 902 } else { 903 table = tableList.get(0); 904 if(Boolean.TRUE.toString().equals(table.getIsDetermined())){ 905 continue; 906 } 907 908 if (option.isIgnoreUnusedSynonym() && SubType.synonym.name().equals(table.getSubType())) { 909 boolean hasSourceRelation = relationParentIds.contains(table.getId()); 910 if (!hasSourceRelation) { 911 dataflow.getTables().remove(table); 912 tableColumnMap.get(tableName).clear(); 913 continue; 914 } 915 } 916 } 917 918 Set<String> columns = tableColumnMap.get(tableName); 919 Iterator<String> columnIter = columns.iterator(); 920 List<column> mergeColumns = new ArrayList<column>(); 921 while (columnIter.hasNext()) { 922 String columnName = columnIter.next(); 923 List<column> columnList = columnMap.get(columnName); 924 List<column> functions = new ArrayList<column>(); 925 for (column t : columnList) { 926 if (Boolean.TRUE.toString().equals(t.getIsFunction())) { 927 functions.add(t); 928 } 929 } 930 if (functions != null && !functions.isEmpty()) { 931 for (column function : functions) { 932 mergeColumns.add(function); 933 columnIdMap.put(function.getId(), function.getId()); 934 columnMergeIdMap.put(function.getId(), function); 935 } 936 937 columnList.removeAll(functions); 938 } 939 if (!columnList.isEmpty()) { 940 column firstColumn = columnList.iterator().next(); 941 if (columnList.size() > 1) { 942 column mergeColumn = new column(); 943 mergeColumn.setId(String.valueOf(++startId)); 944 mergeColumn.setName(firstColumn.getName()); 945 mergeColumn.setDisplayName(firstColumn.getDisplayName()); 946 mergeColumn.setSource(firstColumn.getSource()); 947 mergeColumn.setQualifiedTable(firstColumn.getQualifiedTable()); 948 mergeColumn.setDataType(firstColumn.getDataType()); 949 mergeColumn.setForeignKey(firstColumn.isForeignKey()); 950 mergeColumn.setPrimaryKey(firstColumn.isPrimaryKey()); 951 mergeColumn.setUnqiueKey(firstColumn.isUnqiueKey()); 952 mergeColumn.setIndexKey(firstColumn.isIndexKey()); 953 mergeColumns.add(mergeColumn); 954 for (column item : columnList) { 955 mergeColumn.appendCoordinate(item.getCoordinate()); 956 columnIdMap.put(item.getId(), mergeColumn.getId()); 957 } 958 columnMergeIdMap.put(mergeColumn.getId(), mergeColumn); 959 columnIds.add(mergeColumn.getId()); 960 } else { 961 mergeColumns.add(firstColumn); 962 columnIdMap.put(firstColumn.getId(), firstColumn.getId()); 963 columnMergeIdMap.put(firstColumn.getId(), firstColumn); 964 } 965 } 966 } 967 table.setColumns(mergeColumns); 968 } 969 970 if (dataflow.getRelationships() != null) { 971 Map<String, relationship> mergeRelations = new LinkedHashMap<String, relationship>(); 972 for (int i = 0; i < dataflow.getRelationships().size(); i++) { 973 relationship relation = dataflow.getRelationships().get(i); 974 975 if("crud".equals(relation.getType()) && option.getAnalyzeMode() == AnalyzeMode.crud) { 976 String jsonString = JSON.toJSONString(relation, true); 977 String key = SHA256.getMd5(jsonString); 978 if (!mergeRelations.containsKey(key)) { 979 mergeRelations.put(key, relation); 980 } 981 continue; 982 } 983 984 targetColumn target = relation.getTarget(); 985 if ("call".equals(relation.getType())) { 986 target = relation.getCaller(); 987 } 988 if (target != null && tableIdMap.containsKey(target.getParent_id())) { 989 target.setParent_id(tableIdMap.get(target.getParent_id())); 990 } 991 992 if (columnIdMap.containsKey(target.getId())) { 993 target.setId(columnIdMap.get(target.getId())); 994 target.setCoordinate(columnMergeIdMap.get(target.getId()).getCoordinate()); 995 } 996 else if(option.isIgnoreUnusedSynonym() && EffectType.synonym.name().equals(relation.getEffectType())){ 997 continue; 998 } 999 1000 if (!"call".equals(relation.getType()) && !columnIds.contains(target.getId())) { 1001 continue; 1002 } 1003 1004 List<sourceColumn> sources = relation.getSources(); 1005 if ("call".equals(relation.getType())) { 1006 sources = relation.getCallees(); 1007 } 1008 Set<sourceColumn> sourceSet = new LinkedHashSet<sourceColumn>(); 1009 if (sources != null) { 1010 for (sourceColumn source : sources) { 1011 if (!"call".equals(relation.getType()) && !columnIds.contains(source.getId())) { 1012 continue; 1013 } 1014 if (tableIdMap.containsKey(source.getParent_id())) { 1015 source.setParent_id(tableIdMap.get(source.getParent_id())); 1016 } 1017 if (tableIdMap.containsKey(source.getSource_id())) { 1018 source.setSource_id(tableIdMap.get(source.getSource_id())); 1019 } 1020 if (columnIdMap.containsKey(source.getId())) { 1021 source.setId(columnIdMap.get(source.getId())); 1022 source.setCoordinate(columnMergeIdMap.get(source.getId()).getCoordinate()); 1023 } 1024 } 1025 1026 sourceSet.addAll(sources); 1027 if ("call".equals(relation.getType())) { 1028 relation.setCallees(new ArrayList<sourceColumn>(sourceSet)); 1029 } else { 1030 relation.setSources(new ArrayList<sourceColumn>(sourceSet)); 1031 } 1032 } 1033 1034 String jsonString = JSON.toJSONString(relation, true); 1035 String key = SHA256.getMd5(jsonString); 1036 if (!mergeRelations.containsKey(key)) { 1037 mergeRelations.put(key, relation); 1038 } 1039 } 1040 1041 dataflow.setRelationships(new ArrayList<relationship>(mergeRelations.values())); 1042 } 1043 1044 tableMap.clear(); 1045 tableTypeMap.clear(); 1046 tableIdMap.clear(); 1047 columnMap.clear(); 1048 tableColumnMap.clear(); 1049 columnIdMap.clear(); 1050 columnMergeIdMap.clear(); 1051 tables.clear(); 1052 return dataflow; 1053 } 1054 1055 public synchronized dataflow getDataFlow() { 1056 if (dataflow != null) { 1057 return dataflow; 1058 } else if (dataflowString != null) { 1059 return XML2Model.loadXML(dataflow.class, dataflowString); 1060 } 1061 return null; 1062 } 1063 1064 List<ErrorInfo> metadataErrors = new ArrayList<>(); 1065 1066 private synchronized dataflow analyzeSqlScript() { 1067 init(); 1068 1069 try { 1070 dataflow dataflow = new dataflow(); 1071 1072 if (sqlInfos != null) { 1073 if (option.getHandleListener() != null) { 1074 if (sqlInfos.length == 1) { 1075 option.getHandleListener().startAnalyze(null, sqlInfos[0].getSql().length(), false); 1076 } else { 1077 option.getHandleListener().startAnalyze(null, sqlInfos.length, true); 1078 } 1079 } 1080 1081 if (sqlenv == null) { 1082 if (option.getHandleListener() != null) { 1083 option.getHandleListener().startParseSQLEnv(); 1084 } 1085 TSQLEnv[] sqlenvs = new SQLEnvParser(option.getDefaultServer(), option.getDefaultDatabase(), 1086 option.getDefaultSchema()).parseSQLEnv(option.getVendor(), sqlInfos); 1087 if (sqlenvs != null && sqlenvs.length > 0) { 1088 sqlenv = sqlenvs[0]; 1089 } 1090 if (option.getHandleListener() != null) { 1091 option.getHandleListener().endParseSQLEnv(); 1092 } 1093 } 1094 TGSqlParser sqlparser = new TGSqlParser(option.getVendor()); 1095 Map<String, Pair3<StringBuilder, AtomicInteger, String>> databaseMap = new LinkedHashMap<String, Pair3<StringBuilder, AtomicInteger, String>>(); 1096 for (int i = 0; i < sqlInfos.length; i++) { 1097 SqlInfo sqlInfo = sqlInfos[i]; 1098 if (sqlInfo == null) { 1099 sqlInfoMap.put(String.valueOf(i), new ArrayList<SqlInfo>()); 1100 continue; 1101 } 1102 String sql = sqlInfo.getSql(); 1103 if (SQLUtil.isEmpty(sql) && sqlInfo.getFileName() != null 1104 && new File(sqlInfo.getFileName()).exists()) { 1105 sql = SQLUtil.getFileContent(sqlInfo.getFileName()); 1106 } 1107 if (SQLUtil.isEmpty(sql) && sqlInfo.getFilePath() != null 1108 && new File(sqlInfo.getFilePath()).exists()) { 1109 sql = SQLUtil.getFileContent(sqlInfo.getFilePath()); 1110 } 1111 String sqlTrim = null; 1112 if (sql != null) { 1113 sqlTrim = sql.substring(0, Math.min(sql.length(), 512)).trim(); 1114 } 1115 if(sql!=null && sqlTrim.startsWith("<") && sqlTrim.indexOf("<dlineage")!=-1){ 1116 dataflow temp = XML2Model.loadXML(dataflow.class, sql); 1117 if(sqlInfos.length == 1){ 1118 dataflow = temp; 1119 } 1120 else { 1121 if (temp.getTables() != null) { 1122 dataflow.getTables().addAll(temp.getTables()); 1123 } 1124 if (temp.getViews() != null) { 1125 dataflow.getViews().addAll(temp.getViews()); 1126 } 1127 if (temp.getResultsets() != null) { 1128 dataflow.getResultsets().addAll(temp.getResultsets()); 1129 } 1130 if (temp.getRelationships() != null) { 1131 dataflow.getRelationships().addAll(temp.getRelationships()); 1132 } 1133 if (temp.getErrors() != null) { 1134 dataflow.getErrors().addAll(temp.getErrors()); 1135 } 1136 } 1137 } 1138 else if (sql != null && sqlTrim.startsWith("{")) { 1139 EDbVendor vendor = SQLUtil.isEmpty(sqlInfo.getDbVendor()) ? option.getVendor() 1140 : EDbVendor.valueOf(sqlInfo.getDbVendor()); 1141 TSQLEnv[] sqlenvs = new TJSONSQLEnvParser(option.getDefaultServer(), 1142 option.getDefaultDatabase(), option.getDefaultSchema()).parseSQLEnv(vendor, sql); 1143 if (sqlenvs != null && sqlenvs.length > 0) { 1144 if (sqlenv == null) { 1145 sqlenv = sqlenvs[0]; 1146 } else { 1147 sqlenv = SQLEnvParser.mergeSQLEnv(Arrays.asList(sqlenv, sqlenvs[0])); 1148 } 1149 } 1150 if (sqlenv != null) { 1151 if (MetadataReader.isGrabit(sql) || MetadataReader.isSqlflow(sql) || MetadataReader.isSqlflowSharded(sql)) { 1152 String hash = SHA256.getMd5(sql); 1153 String fileHash = SHA256.getMd5(hash); 1154 if (!sqlInfoMap.containsKey(fileHash)) { 1155 sqlInfoMap.put(fileHash, new ArrayList<SqlInfo>()); 1156 sqlInfoMap.get(fileHash).add(sqlInfo); 1157 } 1158 ModelBindingManager.setGlobalHash(fileHash); 1159 dataflow temp = null; 1160 1161 if (MetadataReader.isGrabit(sql)) { 1162 temp = new GrabitMetadataAnalyzer().analyzeMetadata(option.getVendor(), sql); 1163 } else if (MetadataReader.isSqlflowSharded(sql)) { 1164 String baseDir = null; 1165 if (sqlInfo.getFilePath() != null) { 1166 baseDir = new File(sqlInfo.getFilePath()).getParent(); 1167 } 1168 temp = new SqlflowShardedMetadataAnalyzer(baseDir).analyzeMetadata(option.getVendor(), sql); 1169 } else { 1170 temp = new SqlflowMetadataAnalyzer(sqlenv).analyzeMetadata(option.getVendor(), sql); 1171 } 1172// if (temp.getPackages() != null) { 1173// dataflow.getPackages().addAll(temp.getPackages()); 1174// } 1175// if (temp.getProcedures() != null) { 1176// dataflow.getProcedures().addAll(temp.getProcedures()); 1177// } 1178 if (temp.getTables() != null) { 1179 dataflow.getTables().addAll(temp.getTables()); 1180 } 1181 if (temp.getViews() != null) { 1182 dataflow.getViews().addAll(temp.getViews()); 1183 } 1184 if (temp.getResultsets() != null) { 1185 dataflow.getResultsets().addAll(temp.getResultsets()); 1186 } 1187 if (temp.getRelationships() != null) { 1188 dataflow.getRelationships().addAll(temp.getRelationships()); 1189 } 1190 if (temp.getErrors() != null) { 1191 dataflow.getErrors().addAll(temp.getErrors()); 1192 } 1193 if (sql.indexOf("createdBy") != -1) { 1194 if (sql.toLowerCase().indexOf("sqldep") != -1 1195 || sql.toLowerCase().indexOf("grabit") != -1) { 1196 Map jsonObject = (Map) JSON.parseObject(sql); 1197 List<Map> queries = (List<Map>) jsonObject.get("queries"); 1198 if (queries != null) { 1199 for (int j = 0; j < queries.size(); j++) { 1200 Map queryObject = queries.get(j); 1201 appendSqlInfo(databaseMap, j, sqlInfo, queryObject); 1202 } 1203 } 1204 } else if (sql.toLowerCase().indexOf("sqlflow") != -1) { 1205 Map sqlflow = (Map) JSON.parseObject(sql); 1206 if ("sqlflow-sharded".equals(sqlflow.get("format"))) { 1207 String baseDir = null; 1208 if (sqlInfo.getFilePath() != null) { 1209 baseDir = new File(sqlInfo.getFilePath()).getParent(); 1210 } 1211 String sourceCompression = (String) sqlflow.get("sourceCompression"); 1212 List<Map> servers = (List<Map>) sqlflow.get("servers"); 1213 if (servers != null) { 1214 for (Map serverObject : servers) { 1215 List<Map> databases = (List<Map>) serverObject.get("databases"); 1216 if (databases != null) { 1217 for (Map database : databases) { 1218 Map source = (Map) database.get("source"); 1219 if (source != null) { 1220 String sourcePath = (String) source.get("path"); 1221 if (sourcePath != null && baseDir != null) { 1222 File sourceFile = new File(baseDir, sourcePath); 1223 String fullPath = sourceFile.getAbsolutePath(); 1224 if ("block".equals(sourceCompression)) { 1225 readGzipBlockSource(fullPath, databaseMap, sqlInfo); 1226 } else { 1227 String sourceContent = SQLUtil.getFileContent(fullPath); 1228 if (sourceContent != null) { 1229 String[] lines = sourceContent.split("\\r?\\n"); 1230 for (int j = 0; j < lines.length; j++) { 1231 String line = lines[j].trim(); 1232 if (line.isEmpty()) { 1233 continue; 1234 } 1235 try { 1236 Map sourceObject = (Map) JSON.parseObject(line); 1237 String sourceCode = (String) sourceObject.get("sourceCode"); 1238 if (sourceCode != null && !sourceCode.isEmpty()) { 1239 SqlInfo sourceSqlInfo = new SqlInfo(); 1240 sourceSqlInfo.setFileName(sourceFile.getName()); 1241 sourceSqlInfo.setFilePath(sourceFile.getAbsolutePath()); 1242 sourceSqlInfo.setSql(sourceCode); 1243 sourceSqlInfo.setOriginIndex(j); 1244 appendSqlInfo(databaseMap, j, sourceSqlInfo, sourceObject); 1245 } 1246 } catch (Exception e) { 1247 logger.warn("Parse source jsonl line failed.", e); 1248 } 1249 } 1250 } 1251 } 1252 } 1253 } 1254 } 1255 } 1256 } 1257 } 1258 } else { 1259 List<Map> servers = (List<Map>) sqlflow.get("servers"); 1260 if (servers != null) { 1261 for (Map serverObject : servers) { 1262 List<Map> queries = (List<Map>) serverObject.get("queries"); 1263 if (queries != null) { 1264 for (int j = 0; j < queries.size(); j++) { 1265 Map queryObject = queries.get(j); 1266 appendSqlInfo(databaseMap, j, sqlInfo, queryObject); 1267 } 1268 } 1269 } 1270 } 1271 } 1272 List<Map> errorMessages = (List<Map>) sqlflow.get("errorMessages"); 1273 if(errorMessages!=null && !errorMessages.isEmpty()) { 1274 for(Map error: errorMessages){ 1275 ErrorInfo errorInfo = new ErrorInfo(); 1276 errorInfo.setErrorType(ErrorInfo.METADATA_ERROR); 1277 errorInfo.setErrorMessage((String)error.get("errorMessage")); 1278 errorInfo.setFileName(sqlInfo.getFileName()); 1279 errorInfo.setFilePath(sqlInfo.getFilePath()); 1280 errorInfo.setStartPosition(new Pair3<Long, Long, String>(-1L, -1L, 1281 ModelBindingManager.getGlobalHash())); 1282 errorInfo.setEndPosition(new Pair3<Long, Long, String>(-1L, -1L, 1283 ModelBindingManager.getGlobalHash())); 1284 errorInfo.setOriginStartPosition(new Pair<Long, Long>(-1L, -1L)); 1285 errorInfo.setOriginEndPosition(new Pair<Long, Long>(-1L, -1L)); 1286 metadataErrors.add(errorInfo); 1287 } 1288 } 1289 } 1290 } 1291 } else { 1292 Map queryObject = (Map) JSON.parseObject(sql); 1293 appendSqlInfo(databaseMap, i, sqlInfo, queryObject); 1294 } 1295 } else { 1296 Map queryObject = (Map) JSON.parseObject(sql); 1297 appendSqlInfo(databaseMap, i, sqlInfo, queryObject); 1298 } 1299 } else { 1300 ModelBindingManager.removeGlobalDatabase(); 1301 ModelBindingManager.removeGlobalSchema(); 1302 ModelBindingManager.removeGlobalHash(); 1303 1304 String content = sql; 1305 1306 if (content == null) { 1307 continue; 1308 } 1309 1310 String delimiterChar = String.valueOf(sqlparser.getDelimiterChar()); 1311 1312 if (sqlInfos.length > 1) { 1313 String endTrim = SQLUtil.endTrim(content); 1314 if (endTrim.endsWith(delimiterChar) || endTrim.endsWith(";")) { 1315 content += "\n"; 1316 } else if (option.getVendor() == EDbVendor.dbvredshift 1317 || option.getVendor() == EDbVendor.dbvgaussdb 1318 || option.getVendor() == EDbVendor.dbvedb 1319 || option.getVendor() == EDbVendor.dbvpostgresql 1320 || option.getVendor() == EDbVendor.dbvmysql 1321 || option.getVendor() == EDbVendor.dbvteradata) { 1322 content += ("\n\n-- " + TBaseType.sqlflow_stmt_delimiter_str + "\n\n"); 1323 } else { 1324 content = endTrim + ";" + "\n"; 1325 } 1326 } 1327 1328 sqlInfo.setSql(content); 1329 1330 if (MetadataReader.isMetadata(content)) { 1331 String hash = SHA256.getMd5(content); 1332 ModelBindingManager.setGlobalHash(hash); 1333 dataflow temp = new SQLDepMetadataAnalyzer().analyzeMetadata(option.getVendor(), content); 1334 if (temp.getProcedures() != null) { 1335 dataflow.getProcedures().addAll(temp.getProcedures()); 1336 } 1337 if (temp.getTables() != null) { 1338 dataflow.getTables().addAll(temp.getTables()); 1339 } 1340 if (temp.getViews() != null) { 1341 dataflow.getViews().addAll(temp.getViews()); 1342 } 1343 if (temp.getResultsets() != null) { 1344 dataflow.getResultsets().addAll(temp.getResultsets()); 1345 } 1346 if (temp.getRelationships() != null) { 1347 dataflow.getRelationships().addAll(temp.getRelationships()); 1348 } 1349 if (temp.getErrors() != null) { 1350 dataflow.getErrors().addAll(temp.getErrors()); 1351 } 1352 String fileHash = SHA256.getMd5(hash); 1353 if (!sqlInfoMap.containsKey(fileHash)) { 1354 sqlInfoMap.put(fileHash, new ArrayList<SqlInfo>()); 1355 sqlInfoMap.get(fileHash).add(sqlInfo); 1356 } 1357 } else { 1358 String sqlHash = SHA256.getMd5(content); 1359 String fileHash = SHA256.getMd5(sqlHash); 1360 if (!sqlInfoMap.containsKey(fileHash)) { 1361 sqlInfoMap.put(fileHash, new ArrayList<SqlInfo>()); 1362 } 1363 1364 String database = TSQLEnv.DEFAULT_DB_NAME; 1365 String schema = TSQLEnv.DEFAULT_SCHEMA_NAME; 1366 if (sqlenv != null) { 1367 // Prefer the per-analysis Option default database over the attached 1368 // env's default catalog, so a shared multi-catalog TSQLEnv can be 1369 // reused across analyses with different default databases without 1370 // the env's default catalog deciding name resolution. 1371 if (!SQLUtil.isEmpty(option.getDefaultDatabase()) 1372 && !TSQLEnv.DEFAULT_DB_NAME.equals(option.getDefaultDatabase())) { 1373 database = option.getDefaultDatabase(); 1374 } else { 1375 database = sqlenv.getDefaultCatalogName(); 1376 } 1377 if (database == null) { 1378 database = TSQLEnv.DEFAULT_DB_NAME; 1379 } 1380 schema = sqlenv.getDefaultSchemaName(); 1381 if (schema == null) { 1382 schema = TSQLEnv.DEFAULT_SCHEMA_NAME; 1383 } 1384 } 1385 1386 boolean supportCatalog = TSQLEnv.supportCatalog(option.getVendor()); 1387 boolean supportSchema = TSQLEnv.supportSchema(option.getVendor()); 1388 StringBuilder builder = new StringBuilder(); 1389 if (supportCatalog) { 1390 builder.append(database); 1391 } 1392 if (supportSchema) { 1393 if (builder.length() > 0) { 1394 builder.append("."); 1395 } 1396 builder.append(schema); 1397 } 1398 String group = builder.toString(); 1399 SqlInfo sqlInfoItem = new SqlInfo(); 1400 sqlInfoItem.setFileName(sqlInfo.getFileName()); 1401 sqlInfoItem.setFilePath(sqlInfo.getFilePath()); 1402 sqlInfoItem.setSql(sqlInfo.getSql()); 1403 sqlInfoItem.setOriginIndex(0); 1404 sqlInfoItem.setOriginLineStart(0); 1405 int lineEnd = sqlInfo.getSql().split("\n").length - 1; 1406 sqlInfoItem.setOriginLineEnd(lineEnd); 1407 sqlInfoItem.setIndex(0); 1408 sqlInfoItem.setLineStart(0); 1409 sqlInfoItem.setLineEnd(lineEnd); 1410 sqlInfoItem.setHash(SHA256.getMd5(sqlHash)); 1411 sqlInfoItem.setGroup(group); 1412 sqlInfoMap.get(fileHash).add(sqlInfoItem); 1413 if (!databaseMap.containsKey(sqlHash)) { 1414 databaseMap.put(sqlHash, new Pair3<StringBuilder, AtomicInteger, String>( 1415 new StringBuilder(), new AtomicInteger(), group)); 1416 } 1417 databaseMap.get(sqlHash).first.append(sqlInfoItem.getSql()); 1418 databaseMap.get(sqlHash).second.incrementAndGet(); 1419 } 1420 } 1421 } 1422 1423 boolean supportCatalog = TSQLEnv.supportCatalog(option.getVendor()); 1424 boolean supportSchema = TSQLEnv.supportSchema(option.getVendor()); 1425 1426 Iterator<String> schemaIter = databaseMap.keySet().iterator(); 1427 while (schemaIter.hasNext()) { 1428 if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) { 1429 break; 1430 } 1431 String key = schemaIter.next(); 1432 String group = databaseMap.get(key).third; 1433 String[] split = SQLUtil.parseNames(group).toArray(new String[0]); 1434 1435 ModelBindingManager.removeGlobalDatabase(); 1436 ModelBindingManager.removeGlobalSchema(); 1437 ModelBindingManager.removeGlobalSQLEnv(); 1438 ModelBindingManager.removeGlobalHash(); 1439 1440 String defaultDatabase = null; 1441 String defaultSchema = null; 1442 if(sqlenv!=null){ 1443 defaultDatabase = sqlenv.getDefaultCatalogName(); 1444 defaultSchema = sqlenv.getDefaultSchemaName(); 1445 } 1446 if (supportCatalog && supportSchema) { 1447 if (split.length >= 2) { 1448 if (!TSQLEnv.DEFAULT_DB_NAME.equals(split[split.length - 2])) { 1449 ModelBindingManager.setGlobalDatabase(split[split.length - 2]); 1450 sqlenv.setDefaultCatalogName(ModelBindingManager.getGlobalDatabase()); 1451 } 1452 } 1453 if (split.length >= 1) { 1454 if (!TSQLEnv.DEFAULT_SCHEMA_NAME.equals(split[split.length - 1])) { 1455 ModelBindingManager.setGlobalSchema(split[split.length - 1]); 1456 sqlenv.setDefaultSchemaName(ModelBindingManager.getGlobalSchema()); 1457 } 1458 } 1459 } else if (supportCatalog) { 1460 if (!TSQLEnv.DEFAULT_DB_NAME.equals(split[split.length - 1])) { 1461 ModelBindingManager.setGlobalDatabase(split[split.length - 1]); 1462 sqlenv.setDefaultCatalogName(ModelBindingManager.getGlobalDatabase()); 1463 } 1464 } else if (supportSchema) { 1465 if (!TSQLEnv.DEFAULT_SCHEMA_NAME.equals(split[split.length - 1])) { 1466 ModelBindingManager.setGlobalSchema(split[split.length - 1]); 1467 sqlenv.setDefaultSchemaName(ModelBindingManager.getGlobalSchema()); 1468 } 1469 } 1470 if (option.getHandleListener() != null) { 1471 option.getHandleListener().startParse(null, databaseMap.get(key).first.toString()); 1472 } 1473 1474 if (sqlenv == null) { 1475 sqlenv = new TSQLEnv(option.getVendor()) { 1476 1477 @Override 1478 public void initSQLEnv() { 1479 // TODO Auto-generated method stub 1480 1481 } 1482 }; 1483 } 1484 ModelBindingManager.setGlobalSQLEnv(sqlenv); 1485 sqlparser.sqltext = databaseMap.get(key).first.toString(); 1486 ModelBindingManager.setGlobalHash(SHA256.getMd5(key)); 1487 analyzeAndOutputResult(sqlparser); 1488 if(sqlenv!=null){ 1489 sqlenv.setDefaultCatalogName(defaultDatabase); 1490 sqlenv.setDefaultSchemaName(defaultSchema); 1491 } 1492 } 1493 1494 materializeSqlEnvSynonyms(); 1495 1496 appendProcesses(dataflow); 1497 appendOraclePackages(dataflow); 1498 appendProcedures(dataflow); 1499 appendTables(dataflow); 1500 appendViews(dataflow); 1501 appendResultSets(dataflow); 1502 appendRelations(dataflow); 1503 appendErrors(dataflow); 1504 } 1505 1506 dataflow = handleDataflowExecProcedure(dataflow); 1507 1508 if (dataflow != null && option.getAnalyzeMode() != AnalyzeMode.crud) { 1509 if (!isShowJoin()) { 1510 dataflow = mergeTables(dataflow, modelManager.TABLE_COLUMN_ID, option); 1511 } else { 1512 dataflow = removeDuplicateColumns(dataflow); 1513 } 1514 } 1515 1516 if (dataflow != null && option.isNormalizeOutput()) { 1517 dataflow = getNormalizeDataflow(dataflow); 1518 } 1519 1520 if (dataflow != null && option.isIgnoreCoordinate()) { 1521 dataflow = filterDataflowCoordinate(dataflow); 1522 } 1523 1524 if (option.isSimpleOutput() || option.isIgnoreRecordSet()) { 1525 List<String> showTypes = new ArrayList<>(); 1526 if(option.getSimpleShowRelationTypes()!=null) { 1527 showTypes.addAll(option.getSimpleShowRelationTypes()); 1528 } 1529 if(showTypes.isEmpty()) { 1530 showTypes.add("fdd"); 1531 } 1532 if(option.isShowCallRelation()) { 1533 showTypes.add("call"); 1534 } 1535 if(option.isShowERDiagram()) { 1536 showTypes.add("er"); 1537 } 1538 dataflow simpleDataflow = getSimpleDataflow(dataflow, option.isSimpleOutput(), showTypes); 1539 if (simpleDataflow.getResultsets() != null) { 1540 for (table t : simpleDataflow.getResultsets()) { 1541 t.setIsTarget(null); 1542 } 1543 } 1544 return simpleDataflow; 1545 } else { 1546 return dataflow; 1547 } 1548 1549 } catch (Exception e) { 1550 logger.error("analyze sql failed.", e); 1551 ErrorInfo errorInfo = new ErrorInfo(); 1552 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 1553 if (e.getMessage() == null) { 1554 if (e.getStackTrace() != null && e.getStackTrace().length > 0) { 1555 errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getStackTrace()[0].toString()); 1556 } else { 1557 errorInfo.setErrorMessage(e.getClass().getSimpleName()); 1558 } 1559 } else { 1560 errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getMessage()); 1561 } 1562 errorInfo.fillInfo(this); 1563 errorInfos.add(errorInfo); 1564 } 1565 1566 modelManager.reset(); 1567 return null; 1568 } 1569 1570 private dataflow handleDataflowExecProcedure(dataflow dataflow) { 1571 Set<String> procedures = new HashSet<String>(); 1572 for (procedure procedure : dataflow.getProcedures()) { 1573 procedures.add(DlineageUtil.getIdentifierNormalTableName(procedure.getName())); 1574 } 1575 List<table> removeResultSets = new ArrayList<table>(); 1576 1577 Map<String, table> allMap = new HashMap<String, table>(); 1578 1579 if (dataflow.getResultsets() != null) { 1580 for (table t : dataflow.getResultsets()) { 1581 allMap.put(t.getId().toLowerCase(), t); 1582 } 1583 } 1584 1585 if (dataflow.getTables() != null) { 1586 for (table t : dataflow.getTables()) { 1587 allMap.put(t.getId().toLowerCase(), t); 1588 } 1589 } 1590 1591 if (dataflow.getViews() != null) { 1592 for (table t : dataflow.getViews()) { 1593 allMap.put(t.getId().toLowerCase(), t); 1594 } 1595 } 1596 1597 if (dataflow.getVariables() != null) { 1598 for (table t : dataflow.getVariables()) { 1599 allMap.put(t.getId().toLowerCase(), t); 1600 } 1601 } 1602 1603 1604 for (table resultSet : dataflow.getResultsets()) { 1605 String resultSetName = DlineageUtil.getIdentifierNormalTableName(resultSet.getName()); 1606 if (!(ResultSetType.function.name().equals(resultSet.getType()) 1607 && modelManager.getFunctionTable(resultSetName) != null && procedures.contains(resultSetName))) { 1608 continue; 1609 } 1610 1611 Set<Object> functionTables = modelManager 1612 .getFunctionTable(DlineageUtil.getIdentifierNormalTableName(resultSet.getName())); 1613 List<ResultSet> functionResults = functionTables.stream().filter(t -> t instanceof ResultSet) 1614 .map(t -> (ResultSet) t).collect(Collectors.toList()); 1615 if (!(resultSet.getColumns().size() == 1 1616 && DlineageUtil.getIdentifierNormalTableName(resultSet.getColumns().get(0).getName()).equals(resultSetName)) 1617 || functionResults.isEmpty()) { 1618 continue; 1619 } 1620 1621 column column = resultSet.getColumns().get(0); 1622 String sourceColumnId = column.getId(); 1623 boolean reserveResultSet = false; 1624 List<relationship> appendRelations = new ArrayList<relationship>(); 1625 Set<relationship> removeRelations = new HashSet<relationship>(); 1626 1627 for (relationship relationship : dataflow.getRelationships()) { 1628 targetColumn targetColumn = relationship.getTarget(); 1629 List<sourceColumn> sourceColumns = relationship.getSources(); 1630 List<sourceColumn> newSourceColumns = new ArrayList<sourceColumn>(); 1631 for (sourceColumn sourceColumn : sourceColumns) { 1632 if (!sourceColumn.getId().equals(sourceColumnId)) { 1633 continue; 1634 } 1635 for (ResultSet sourceResultSet : functionResults) { 1636 for (ResultColumn resultColumn : sourceResultSet.getColumns()) { 1637 if (!DlineageUtil.compareColumnIdentifier(resultColumn.getName(), 1638 targetColumn.getColumn())) { 1639 if (targetColumn.getColumn().endsWith("*")) { 1640 table parent = allMap.get(targetColumn.getParent_id()); 1641 if (parent != null && parent.getColumns().size() > 1) { 1642 for (column item : parent.getColumns()) { 1643 if (DlineageUtil.compareColumnIdentifier(resultColumn.getName(), 1644 item.getName())) { 1645 relationship newRelation = appendStarRelation(dataflow, relationship, item, resultColumn); 1646 appendRelations.add(newRelation); 1647 removeRelations.add(relationship); 1648 newSourceColumns.add(newRelation.getSources().get(0)); 1649 if (resultColumn.getResultSet() != null && resultColumn.getResultSet().isTarget()) { 1650 dataflow.getResultsets().stream().filter( 1651 t -> t.getId().equals(String.valueOf(resultColumn.getResultSet().getId()))) 1652 .forEach(t -> t.setIsTarget(Boolean.FALSE.toString())); 1653 } 1654 } 1655 } 1656 } 1657 } 1658 continue; 1659 } 1660 1661 sourceColumn sourceColumn1 = new sourceColumn(); 1662 sourceColumn1.setId(String.valueOf(resultColumn.getId())); 1663 sourceColumn1.setColumn(resultColumn.getName()); 1664 sourceColumn1.setParent_id(String.valueOf(resultColumn.getResultSet().getId())); 1665 sourceColumn1.setParent_name(getResultSetName(resultColumn.getResultSet())); 1666 if (resultColumn.getStartPosition() != null 1667 && resultColumn.getEndPosition() != null) { 1668 sourceColumn1.setCoordinate(convertCoordinate(resultColumn.getStartPosition()) 1669 + "," + convertCoordinate(resultColumn.getEndPosition())); 1670 } 1671 newSourceColumns.add(sourceColumn1); 1672 1673 if (resultColumn.getResultSet() != null && resultColumn.getResultSet().isTarget()) { 1674 dataflow.getResultsets().stream().filter( 1675 t -> t.getId().equals(String.valueOf(resultColumn.getResultSet().getId()))) 1676 .forEach(t -> t.setIsTarget(Boolean.FALSE.toString())); 1677 } 1678 } 1679 } 1680 1681 if (!newSourceColumns.isEmpty()) { 1682 if (removeRelations.isEmpty()) { 1683 relationship.setSources(newSourceColumns); 1684 } 1685 } 1686 else { 1687 reserveResultSet = true; 1688 } 1689 } 1690 } 1691 1692 dataflow.getRelationships().addAll(appendRelations); 1693 dataflow.getRelationships().removeAll(removeRelations); 1694 1695 if(!reserveResultSet) { 1696 removeResultSets.add(resultSet); 1697 } 1698 } 1699 dataflow.getResultsets().removeAll(removeResultSets); 1700 return dataflow; 1701 } 1702 1703 private relationship appendStarRelation(dataflow dataflow, 1704 relationship relationship, column item, ResultColumn resultColumn) { 1705 relationship relationElement = new relationship(); 1706 relationElement.setType(relationship.getType()); 1707 relationElement.setEffectType(relationship.getEffectType()); 1708 relationElement.setSqlHash(relationship.getSqlHash()); 1709 relationElement.setSqlComment(relationship.getSqlComment()); 1710 relationElement.setProcedureId(relationship.getProcedureId()); 1711 relationElement.setId(String.valueOf(++ModelBindingManager.get().RELATION_ID)); 1712 relationElement.setProcessId(relationship.getProcessId()); 1713 relationElement.setProcessType(relationship.getProcessType()); 1714 1715 targetColumn targetColumn1 = new targetColumn(); 1716 targetColumn1.setId(String.valueOf(item.getId())); 1717 targetColumn1.setColumn(item.getName()); 1718 targetColumn1.setParent_id(relationship.getTarget().getParent_id()); 1719 targetColumn1.setParent_name(relationship.getTarget().getParent_name()); 1720 targetColumn1.setParent_alias(relationship.getTarget().getParent_alias()); 1721 if (relationship.getTarget().getCoordinate() != null) { 1722 targetColumn1.setCoordinate(item.getCoordinate()); 1723 } 1724 relationElement.setTarget(targetColumn1); 1725 1726 sourceColumn sourceColumn1 = new sourceColumn(); 1727 sourceColumn1.setId(String.valueOf(resultColumn.getId())); 1728 sourceColumn1.setColumn(resultColumn.getName()); 1729 sourceColumn1.setParent_id(String.valueOf(resultColumn.getResultSet().getId())); 1730 sourceColumn1.setParent_name(getResultSetName(resultColumn.getResultSet())); 1731 if (resultColumn.getStartPosition() != null 1732 && resultColumn.getEndPosition() != null) { 1733 sourceColumn1.setCoordinate(convertCoordinate(resultColumn.getStartPosition()) 1734 + "," + convertCoordinate(resultColumn.getEndPosition())); 1735 } 1736 relationElement.addSource(sourceColumn1); 1737 return relationElement; 1738 } 1739 1740 private dataflow getNormalizeDataflow(dataflow instance) { 1741 List<table> tables = new ArrayList<>(); 1742 if (instance.getResultsets() != null) { 1743 for (table t : instance.getResultsets()) { 1744 tables.add(t); 1745 } 1746 } 1747 1748 if (instance.getTables() != null) { 1749 for (table t : instance.getTables()) { 1750 tables.add(t); 1751 } 1752 } 1753 1754 if (instance.getViews() != null) { 1755 for (table t : instance.getViews()) { 1756 tables.add(t); 1757 } 1758 } 1759 1760 if (instance.getPaths() != null) { 1761 for (table t : instance.getPaths()) { 1762 tables.add(t); 1763 } 1764 } 1765 1766 if (instance.getStages() != null) { 1767 for (table t : instance.getStages()) { 1768 tables.add(t); 1769 } 1770 } 1771 1772 if (instance.getSequences() != null) { 1773 for (table t : instance.getSequences()) { 1774 tables.add(t); 1775 } 1776 } 1777 1778 if (instance.getDatasources() != null) { 1779 for (table t : instance.getDatasources()) { 1780 tables.add(t); 1781 } 1782 } 1783 1784 if (instance.getDatabases() != null) { 1785 for (table t : instance.getDatabases()) { 1786 tables.add(t); 1787 } 1788 } 1789 1790 if (instance.getSchemas() != null) { 1791 for (table t : instance.getSchemas()) { 1792 tables.add(t); 1793 } 1794 } 1795 1796 if (instance.getStreams() != null) { 1797 for (table t : instance.getStreams()) { 1798 tables.add(t); 1799 } 1800 } 1801 1802 if (instance.getVariables() != null) { 1803 for (table t : instance.getVariables()) { 1804 tables.add(t); 1805 } 1806 } 1807 1808 Map<String, String> idNameMap = new HashMap(); 1809 1810 for(table table: tables){ 1811 if(table.getDatabase()!=null) { 1812 table.setDatabase(DlineageUtil.getIdentifierNormalName(table.getDatabase(), ESQLDataObjectType.dotCatalog)); 1813 } 1814 if(table.getSchema()!=null) { 1815 table.setSchema(DlineageUtil.getIdentifierNormalName(table.getSchema(), ESQLDataObjectType.dotSchema)); 1816 } 1817 if(table.getName()!=null) { 1818 table.setName(DlineageUtil.getIdentifierNormalName(table.getName(), ESQLDataObjectType.dotTable)); 1819 idNameMap.put(table.getId(), table.getName()); 1820 } 1821 if(table.getColumns()!=null){ 1822 for(column column: table.getColumns()){ 1823 column.setName(DlineageUtil.getIdentifierNormalName(column.getName(), ESQLDataObjectType.dotColumn)); 1824 idNameMap.put(column.getId(), column.getName()); 1825 } 1826 } 1827 } 1828 if(instance.getPackages()!=null){ 1829 for(oraclePackage oraclePackage: instance.getPackages()){ 1830 if(oraclePackage.getDatabase()!=null) { 1831 oraclePackage.setDatabase(DlineageUtil.getIdentifierNormalName(oraclePackage.getDatabase(), ESQLDataObjectType.dotCatalog)); 1832 } 1833 if(oraclePackage.getSchema()!=null) { 1834 oraclePackage.setSchema(DlineageUtil.getIdentifierNormalName(oraclePackage.getSchema(), ESQLDataObjectType.dotSchema)); 1835 } 1836 if(oraclePackage.getName()!=null) { 1837 oraclePackage.setName(DlineageUtil.getIdentifierNormalName(oraclePackage.getName(), ESQLDataObjectType.dotTable)); 1838 idNameMap.put(oraclePackage.getId(), oraclePackage.getName()); 1839 } 1840 if(oraclePackage.getArguments()!=null){ 1841 for(argument argument: oraclePackage.getArguments()){ 1842 argument.setName(DlineageUtil.getIdentifierNormalName(argument.getName(), ESQLDataObjectType.dotColumn)); 1843 idNameMap.put(argument.getId(), argument.getName()); 1844 } 1845 } 1846 if(oraclePackage.getProcedures()!=null){ 1847 for(procedure procedure: oraclePackage.getProcedures()){ 1848 if(procedure.getDatabase()!=null) { 1849 procedure.setDatabase(DlineageUtil.getIdentifierNormalName(procedure.getDatabase(), ESQLDataObjectType.dotCatalog)); 1850 } 1851 if(procedure.getSchema()!=null) { 1852 procedure.setSchema(DlineageUtil.getIdentifierNormalName(procedure.getSchema(), ESQLDataObjectType.dotSchema)); 1853 } 1854 if(procedure.getName()!=null) { 1855 procedure.setName(DlineageUtil.getIdentifierNormalName(procedure.getName(), ESQLDataObjectType.dotTable)); 1856 idNameMap.put(procedure.getId(), procedure.getName()); 1857 } 1858 for(argument argument: procedure.getArguments()){ 1859 argument.setName(DlineageUtil.getIdentifierNormalName(argument.getName(), ESQLDataObjectType.dotColumn)); 1860 idNameMap.put(argument.getId(), argument.getName()); 1861 } 1862 } 1863 } 1864 } 1865 } 1866 if(instance.getProcedures()!=null){ 1867 for(procedure procedure: instance.getProcedures()){ 1868 if(procedure.getDatabase()!=null) { 1869 procedure.setDatabase(DlineageUtil.getIdentifierNormalName(procedure.getDatabase(), ESQLDataObjectType.dotCatalog)); 1870 } 1871 if(procedure.getSchema()!=null) { 1872 procedure.setSchema(DlineageUtil.getIdentifierNormalName(procedure.getSchema(), ESQLDataObjectType.dotSchema)); 1873 } 1874 if(procedure.getName()!=null) { 1875 procedure.setName(DlineageUtil.getIdentifierNormalName(procedure.getName(), ESQLDataObjectType.dotTable)); 1876 idNameMap.put(procedure.getId(), procedure.getName()); 1877 } 1878 for(argument argument: procedure.getArguments()){ 1879 argument.setName(DlineageUtil.getIdentifierNormalName(argument.getName(), ESQLDataObjectType.dotColumn)); 1880 idNameMap.put(argument.getId(), argument.getName()); 1881 } 1882 } 1883 } 1884 if (instance.getProcesses() != null) { 1885 for (process process : instance.getProcesses()) { 1886 if(process.getDatabase()!=null) { 1887 process.setDatabase(DlineageUtil.getIdentifierNormalName(process.getDatabase(), ESQLDataObjectType.dotCatalog)); 1888 } 1889 if(process.getSchema()!=null) { 1890 process.setSchema(DlineageUtil.getIdentifierNormalName(process.getSchema(), ESQLDataObjectType.dotSchema)); 1891 } 1892 if (process.getProcedureId() != null) { 1893 process.setProcedureName(DlineageUtil.getIdentifierNormalName(process.getProcedureName(), ESQLDataObjectType.dotTable)); 1894 idNameMap.put(process.getId(), process.getName()); 1895 } 1896 } 1897 } 1898 1899 if(instance.getRelationships()!=null){ 1900 for(relationship relation: instance.getRelationships()){ 1901 targetColumn targetColumn = relation.getTarget(); 1902 if(targetColumn != null) { 1903 targetColumn.setColumn(idNameMap.get(targetColumn.getId())); 1904 targetColumn.setTarget_name(idNameMap.get(targetColumn.getTarget_id())); 1905 targetColumn.setParent_name(idNameMap.get(targetColumn.getParent_id())); 1906 } 1907 List<sourceColumn> sourceColumns = relation.getSources(); 1908 if(sourceColumns!=null){ 1909 for(sourceColumn sourceColumn: sourceColumns){ 1910 sourceColumn.setColumn(idNameMap.get(sourceColumn.getId())); 1911 sourceColumn.setSource_name(idNameMap.get(sourceColumn.getSource_id())); 1912 sourceColumn.setParent_name(idNameMap.get(sourceColumn.getParent_id())); 1913 } 1914 } 1915 targetColumn = relation.getCaller(); 1916 if(targetColumn != null) { 1917 targetColumn.setName(idNameMap.get(targetColumn.getId())); 1918 } 1919 sourceColumns = relation.getCallees(); 1920 if(sourceColumns!=null){ 1921 for(sourceColumn sourceColumn: sourceColumns){ 1922 sourceColumn.setName(idNameMap.get(sourceColumn.getId())); 1923 } 1924 } 1925 } 1926 } 1927 1928 1929 return instance; 1930 } 1931 1932 private dataflow filterDataflowCoordinate(dataflow instance) { 1933 List<table> tables = new ArrayList<>(); 1934 if (instance.getResultsets() != null) { 1935 for (table t : instance.getResultsets()) { 1936 tables.add(t); 1937 } 1938 } 1939 1940 if (instance.getTables() != null) { 1941 for (table t : instance.getTables()) { 1942 tables.add(t); 1943 } 1944 } 1945 1946 if (instance.getViews() != null) { 1947 for (table t : instance.getViews()) { 1948 tables.add(t); 1949 } 1950 } 1951 1952 if (instance.getPaths() != null) { 1953 for (table t : instance.getPaths()) { 1954 tables.add(t); 1955 } 1956 } 1957 1958 if (instance.getStages() != null) { 1959 for (table t : instance.getStages()) { 1960 tables.add(t); 1961 } 1962 } 1963 1964 if (instance.getSequences() != null) { 1965 for (table t : instance.getSequences()) { 1966 tables.add(t); 1967 } 1968 } 1969 1970 if (instance.getDatasources() != null) { 1971 for (table t : instance.getDatasources()) { 1972 tables.add(t); 1973 } 1974 } 1975 1976 if (instance.getDatabases() != null) { 1977 for (table t : instance.getDatabases()) { 1978 tables.add(t); 1979 } 1980 } 1981 1982 if (instance.getSchemas() != null) { 1983 for (table t : instance.getSchemas()) { 1984 tables.add(t); 1985 } 1986 } 1987 1988 if (instance.getStreams() != null) { 1989 for (table t : instance.getStreams()) { 1990 tables.add(t); 1991 } 1992 } 1993 1994 if (instance.getVariables() != null) { 1995 for (table t : instance.getVariables()) { 1996 tables.add(t); 1997 } 1998 } 1999 2000 for(table table: tables){ 2001 table.clearCoordinate(); 2002 if(table.getColumns()!=null){ 2003 for(column column: table.getColumns()){ 2004 column.clearCoordinate(); 2005 } 2006 } 2007 } 2008 if(instance.getPackages()!=null){ 2009 for(oraclePackage oraclePackage: instance.getPackages()){ 2010 oraclePackage.setCoordinate(null); 2011 if(oraclePackage.getProcedures()!=null){ 2012 for(procedure procedure: oraclePackage.getProcedures()){ 2013 procedure.setCoordinate(null); 2014 for(argument argument: procedure.getArguments()){ 2015 argument.setCoordinate(null); 2016 } 2017 } 2018 } 2019 } 2020 } 2021 if(instance.getProcedures()!=null){ 2022 for(procedure procedure: instance.getProcedures()){ 2023 procedure.setCoordinate(null); 2024 for(argument argument: procedure.getArguments()){ 2025 argument.setCoordinate(null); 2026 } 2027 } 2028 } 2029 if (instance.getProcesses() != null) { 2030 for (process process : instance.getProcesses()) { 2031 process.setCoordinate(null); 2032 } 2033 } 2034 2035 if(instance.getRelationships()!=null){ 2036 for(relationship relation: instance.getRelationships()){ 2037 targetColumn targetColumn = relation.getTarget(); 2038 if(targetColumn != null) { 2039 targetColumn.setCoordinate(null); 2040 } 2041 List<sourceColumn> sourceColumns = relation.getSources(); 2042 if(sourceColumns!=null){ 2043 for(sourceColumn sourceColumn: sourceColumns){ 2044 sourceColumn.setCoordinate(null); 2045 } 2046 } 2047 targetColumn = relation.getCaller(); 2048 if(targetColumn != null) { 2049 targetColumn.setCoordinate(null); 2050 } 2051 sourceColumns = relation.getCallees(); 2052 if(sourceColumns!=null){ 2053 for(sourceColumn sourceColumn: sourceColumns){ 2054 sourceColumn.setCoordinate(null); 2055 } 2056 } 2057 } 2058 } 2059 2060 return instance; 2061 } 2062 2063 private void appendSqlInfo(Map<String, Pair3<StringBuilder, AtomicInteger, String>> databaseMap, int index, 2064 SqlInfo sqlInfo, Map queryObject) { 2065 EDbVendor vendor = option.getVendor(); 2066 if (!SQLUtil.isEmpty(sqlInfo.getDbVendor())) { 2067 vendor = EDbVendor.valueOf(sqlInfo.getDbVendor()); 2068 } 2069 2070 boolean supportCatalog = TSQLEnv.supportCatalog(vendor); 2071 boolean supportSchema = TSQLEnv.supportSchema(vendor); 2072 2073 String groupName = (String) queryObject.get("groupName"); 2074 if (DlineageUtil.isProcedureExcluded(groupName)) { 2075 return; 2076 } 2077 2078 String content = (String) queryObject.get("sourceCode"); 2079 if (SQLUtil.isEmpty(content)) { 2080 return; 2081 } 2082 StringBuilder builder = new StringBuilder(); 2083 if (supportCatalog) { 2084 String database = (String) queryObject.get("database"); 2085 if (database.indexOf(".") != -1) { 2086 String delimitedChar = TSQLEnv.delimitedChar(vendor); 2087 database = delimitedChar + SQLUtil.trimColumnStringQuote(database) + delimitedChar; 2088 } 2089 builder.append(database); 2090 } 2091 if (supportSchema) { 2092 String schema = (String) queryObject.get("schema"); 2093 if (schema.indexOf(".") != -1) { 2094 String delimitedChar = TSQLEnv.delimitedChar(vendor); 2095 schema = delimitedChar + SQLUtil.trimColumnStringQuote(schema) + delimitedChar; 2096 } 2097 if (builder.length() > 0) { 2098 builder.append("."); 2099 } 2100 builder.append(schema); 2101 } 2102 String group = builder.toString(); 2103 String sqlHash = SHA256.getMd5(content); 2104 String hash = SHA256.getMd5(sqlHash); 2105 if (!databaseMap.containsKey(sqlHash)) { 2106 databaseMap.put(sqlHash, 2107 new Pair3<StringBuilder, AtomicInteger, String>(new StringBuilder(), new AtomicInteger(), group)); 2108 } 2109 String delimiterChar = String.valueOf(TGSqlParser.getDelimiterChar(option.getVendor())); 2110 StringBuilder buffer = new StringBuilder(content); 2111 if (content.trim().endsWith(delimiterChar) || content.trim().endsWith(";")) { 2112 buffer.append("\n"); 2113 } else if(vendor == EDbVendor.dbvredshift 2114 || vendor == EDbVendor.dbvgaussdb 2115 || vendor == EDbVendor.dbvedb 2116 || vendor == EDbVendor.dbvpostgresql 2117 || vendor == EDbVendor.dbvmysql 2118 || vendor == EDbVendor.dbvteradata){ 2119 buffer.append("\n\n-- " + TBaseType.sqlflow_stmt_delimiter_str + "\n\n"); 2120 } else{ 2121 SQLUtil.endTrim(buffer); 2122 buffer.append(";").append("\n"); 2123 } 2124 2125 int lineStart = databaseMap.get(sqlHash).first.toString().split("\n", -1).length - 1; 2126 if (databaseMap.get(sqlHash).first.toString().length() == 0) { 2127 lineStart = 0; 2128 } 2129 databaseMap.get(sqlHash).first.append(buffer.toString()); 2130 SqlInfo sqlInfoItem = new SqlInfo(); 2131 sqlInfoItem.setServer(sqlInfo.getServer()); 2132 sqlInfoItem.setDbVendor(sqlInfo.getDbVendor()); 2133 sqlInfoItem.setFileName(sqlInfo.getFileName()); 2134 sqlInfoItem.setFilePath(sqlInfo.getFilePath()); 2135 sqlInfoItem.setSql(buffer.toString()); 2136 sqlInfoItem.setOriginIndex(index); 2137 sqlInfoItem.setOriginLineStart(0); 2138 sqlInfoItem.setOriginLineEnd(buffer.toString().split("\n", -1).length - 1); 2139 sqlInfoItem.setIndex(databaseMap.get(sqlHash).second.getAndIncrement()); 2140 sqlInfoItem.setLineStart(lineStart); 2141 sqlInfoItem.setLineEnd(databaseMap.get(sqlHash).first.toString().split("\n", -1).length - 1); 2142 sqlInfoItem.setGroup(group); 2143 sqlInfoItem.setHash(hash); 2144 2145 if (!sqlInfoMap.containsKey(hash)) { 2146 sqlInfoMap.put(hash, new ArrayList<SqlInfo>()); 2147 } 2148 sqlInfoMap.get(hash).add(sqlInfoItem); 2149 } 2150 2151 private void readGzipBlockSource(String fullPath, Map<String, Pair3<StringBuilder, AtomicInteger, String>> databaseMap, SqlInfo sqlInfo) { 2152 try (FileInputStream fis = new FileInputStream(fullPath); 2153 GZIPInputStream gzis = new GZIPInputStream(fis); 2154 BufferedReader reader = new BufferedReader(new InputStreamReader(gzis, "UTF-8"))) { 2155 String line; 2156 int j = 0; 2157 while ((line = reader.readLine()) != null) { 2158 line = line.trim(); 2159 if (line.isEmpty()) { 2160 continue; 2161 } 2162 try { 2163 Map sourceObject = (Map) JSON.parseObject(line); 2164 String sourceCode = (String) sourceObject.get("sourceCode"); 2165 if (sourceCode != null && !sourceCode.isEmpty()) { 2166 SqlInfo sourceSqlInfo = new SqlInfo(); 2167 sourceSqlInfo.setFileName(sqlInfo.getFileName()); 2168 sourceSqlInfo.setFilePath(sqlInfo.getFilePath()); 2169 sourceSqlInfo.setSql(sourceCode); 2170 sourceSqlInfo.setOriginIndex(j); 2171 appendSqlInfo(databaseMap, j, sourceSqlInfo, null); 2172 } 2173 } catch (Exception e) { 2174 logger.warn("Parse gzip source jsonl line failed.", e); 2175 } 2176 j++; 2177 } 2178 } catch (Exception e) { 2179 logger.warn("Read gzip source file failed: " + fullPath, e); 2180 } 2181 } 2182 2183 static String getTextOutput(dataflow dataflow) { 2184 StringBuffer buffer = new StringBuffer(); 2185 List<relationship> relations = dataflow.getRelationships(); 2186 if (relations != null) { 2187 for (int i = 0; i < relations.size(); i++) { 2188 relationship relation = relations.get(i); 2189 targetColumn target = relation.getTarget(); 2190 List<sourceColumn> sources = relation.getSources(); 2191 if (target != null && sources != null && sources.size() > 0) { 2192 buffer.append(target.getColumn()).append(" depends on: "); 2193 Set<String> columnSet = new LinkedHashSet<String>(); 2194 for (int j = 0; j < sources.size(); j++) { 2195 sourceColumn sourceColumn = sources.get(j); 2196 String columnName = sourceColumn.getColumn(); 2197 if (sourceColumn.getParent_name() != null && sourceColumn.getParent_name().length() > 0) { 2198 columnName = sourceColumn.getParent_name() + "." + columnName; 2199 } 2200 columnSet.add(columnName); 2201 } 2202 String[] columns = columnSet.toArray(new String[0]); 2203 for (int j = 0; j < columns.length; j++) { 2204 buffer.append(columns[j]); 2205 if (j == columns.length - 1) { 2206 buffer.append("\n"); 2207 } else 2208 buffer.append(", "); 2209 } 2210 } 2211 } 2212 } 2213 return buffer.toString(); 2214 } 2215 2216 private String mergeRelationType(List<Pair<sourceColumn, List<String>>> typePaths) { 2217 RelationshipType relationType = RelationshipType.join; 2218 for (int i = 0; i < typePaths.size(); i++) { 2219 List<String> path = typePaths.get(i).second; 2220 RelationshipType type = RelationshipType.valueOf(getRelationType(path)); 2221 if (type.ordinal() < relationType.ordinal()) { 2222 relationType = type; 2223 } 2224 } 2225 return relationType.name(); 2226 } 2227 2228 private String getRelationType(List<String> typePaths) { 2229 if (typePaths.contains("join")) 2230 return "join"; 2231 if (typePaths.contains("fdr")) 2232 return "fdr"; 2233 if (typePaths.contains("frd")) 2234 return "frd"; 2235 if (typePaths.contains("fddi")) 2236 return "fddi"; 2237 return "fdd"; 2238 } 2239 2240 public dataflow getSimpleDataflow(dataflow instance, boolean simpleOutput) throws Exception { 2241 return getSimpleDataflow(instance, simpleOutput, Arrays.asList("fdd")); 2242 } 2243 2244 public dataflow getSimpleDataflow(dataflow instance, boolean simpleOutput, List<String> types) throws Exception { 2245 ModelBindingManager.setGlobalVendor(option.getVendor()); 2246 allMap.clear(); 2247 targetTables.clear(); 2248 resultSetMap.clear(); 2249 tableMap.clear(); 2250 viewMap.clear(); 2251 cursorMap.clear(); 2252 variableMap.clear(); 2253 fileMap.clear(); 2254 stageMap.clear(); 2255 sequenceMap.clear(); 2256 dataSourceMap.clear(); 2257 databaseMap.clear(); 2258 schemaMap.clear(); 2259 streamMap.clear(); 2260 dataflow simple = new dataflow(); 2261 List<relationship> simpleRelations = new ArrayList<relationship>(); 2262 List<relationship> relations = instance.getRelationships(); 2263 if (instance.getResultsets() != null) { 2264 for (table t : instance.getResultsets()) { 2265 resultSetMap.put(t.getId().toLowerCase(), t); 2266 allMap.put(t.getId().toLowerCase(), t); 2267 } 2268 } 2269 2270 if (instance.getTables() != null) { 2271 for (table t : instance.getTables()) { 2272 tableMap.put(t.getId().toLowerCase(), t); 2273 allMap.put(t.getId().toLowerCase(), t); 2274 } 2275 } 2276 2277 if (instance.getViews() != null) { 2278 for (table t : instance.getViews()) { 2279 viewMap.put(t.getId().toLowerCase(), t); 2280 allMap.put(t.getId().toLowerCase(), t); 2281 } 2282 } 2283 2284 if (instance.getPaths() != null) { 2285 for (table t : instance.getPaths()) { 2286 fileMap.put(t.getId().toLowerCase(), t); 2287 allMap.put(t.getId().toLowerCase(), t); 2288 } 2289 } 2290 2291 if (instance.getStages() != null) { 2292 for (table t : instance.getStages()) { 2293 stageMap.put(t.getId().toLowerCase(), t); 2294 allMap.put(t.getId().toLowerCase(), t); 2295 } 2296 } 2297 2298 if (instance.getSequences() != null) { 2299 for (table t : instance.getSequences()) { 2300 sequenceMap.put(t.getId().toLowerCase(), t); 2301 allMap.put(t.getId().toLowerCase(), t); 2302 } 2303 } 2304 2305 if (instance.getDatasources() != null) { 2306 for (table t : instance.getDatasources()) { 2307 dataSourceMap.put(t.getId().toLowerCase(), t); 2308 allMap.put(t.getId().toLowerCase(), t); 2309 } 2310 } 2311 2312 if (instance.getDatabases() != null) { 2313 for (table t : instance.getDatabases()) { 2314 databaseMap.put(t.getId().toLowerCase(), t); 2315 allMap.put(t.getId().toLowerCase(), t); 2316 } 2317 } 2318 2319 if (instance.getSchemas() != null) { 2320 for (table t : instance.getSchemas()) { 2321 schemaMap.put(t.getId().toLowerCase(), t); 2322 allMap.put(t.getId().toLowerCase(), t); 2323 } 2324 } 2325 2326 if (instance.getStreams() != null) { 2327 for (table t : instance.getStreams()) { 2328 streamMap.put(t.getId().toLowerCase(), t); 2329 allMap.put(t.getId().toLowerCase(), t); 2330 } 2331 } 2332 2333 if (instance.getVariables() != null) { 2334 for (table t : instance.getVariables()) { 2335 if(SubType.cursor.name().equals(t.getSubType())){ 2336 cursorMap.put(t.getId().toLowerCase(), t); 2337 } 2338 else { 2339 variableMap.put(t.getId().toLowerCase(), t); 2340 } 2341 allMap.put(t.getId().toLowerCase(), t); 2342 } 2343 } 2344 2345 if (relations != null) { 2346 2347 List<relationship> filterRelations = new ArrayList<>(); 2348 for (relationship relationElem : relations) { 2349 if (!types.contains(relationElem.getType())) 2350 continue; 2351 else { 2352 filterRelations.add(relationElem); 2353 } 2354 } 2355 2356 relations = filterRelations; 2357 2358 Map<String, Set<relationship>> targetIdRelationMap = new HashMap<String, Set<relationship>>(); 2359 for (relationship relation : relations) { 2360 if (relation.getTarget() != null) { 2361 String key = relation.getTarget().getParent_id() + "." + relation.getTarget().getId(); 2362 if (!targetIdRelationMap.containsKey(key)) { 2363 targetIdRelationMap.put(key, new TreeSet<relationship>(new Comparator<relationship>() { 2364 @Override 2365 public int compare(relationship o1, relationship o2) { 2366 return o1.getId().compareTo(o2.getId()); 2367 } 2368 })); 2369 } 2370 targetIdRelationMap.get(key).add(relation); 2371 } 2372 } 2373 2374 Iterator<String> keys = targetIdRelationMap.keySet().iterator(); 2375 while (keys.hasNext()) { 2376 String key = keys.next(); 2377 if (targetIdRelationMap.get(key).size() > 500) { 2378 keys.remove(); 2379 } 2380 } 2381 2382 for (relationship relationElem : relations) { 2383 if (RelationshipType.call.name().equals(relationElem.getType())) { 2384 continue; 2385 } 2386 if (RelationshipType.er.name().equals(relationElem.getType())) { 2387 continue; 2388 } 2389 targetColumn target = relationElem.getTarget(); 2390 String targetParent = target.getParent_id(); 2391 if (isTarget(instance, targetParent, simpleOutput)) { 2392 List<Pair<sourceColumn, List<String>>> relationSources = new ArrayList<Pair<sourceColumn, List<String>>>(); 2393 findSourceRelations(target, instance, targetIdRelationMap, relationElem, relationSources, 2394 new String[] { relationElem.getType() }, simpleOutput); 2395 if (relationSources.size() > 0) { 2396 Map<sourceColumn, List<Pair<sourceColumn, List<String>>>> columnMap = new LinkedHashMap<sourceColumn, List<Pair<sourceColumn, List<String>>>>(); 2397 for (Pair<sourceColumn, List<String>> t : relationSources) { 2398 sourceColumn key = ((Pair<sourceColumn, List<String>>) t).first; 2399 if (!columnMap.containsKey(key)) { 2400 columnMap.put(key, new ArrayList<Pair<sourceColumn, List<String>>>()); 2401 } 2402 columnMap.get(key).add(t); 2403 } 2404 Iterator<sourceColumn> iter = columnMap.keySet().iterator(); 2405 Map<String, List<sourceColumn>> relationSourceMap = new HashMap<String, List<sourceColumn>>(); 2406 while (iter.hasNext()) { 2407 sourceColumn column = iter.next(); 2408 String relationType = mergeRelationType(columnMap.get(column)); 2409 if (!relationSourceMap.containsKey(relationType)) { 2410 relationSourceMap.put(relationType, new ArrayList<sourceColumn>()); 2411 } 2412 relationSourceMap.get(relationType).add(column); 2413 } 2414 2415 Iterator<String> sourceIter = relationSourceMap.keySet().iterator(); 2416 while (sourceIter.hasNext()) { 2417 String relationType = sourceIter.next(); 2418 relationship simpleRelation = (relationship) relationElem.clone(); 2419 simpleRelation.setSources(relationSourceMap.get(relationType)); 2420 simpleRelation.setType(relationType); 2421 simpleRelation.setId(String.valueOf(++ModelBindingManager.get().RELATION_ID)); 2422 simpleRelations.add(simpleRelation); 2423 } 2424 } 2425 } 2426 } 2427 } 2428 2429 simple.setProcedures(instance.getProcedures()); 2430 simple.setPackages(instance.getPackages()); 2431 simple.setProcesses(instance.getProcesses()); 2432 simple.setErrors(instance.getErrors()); 2433 List<table> tables = new ArrayList<table>(); 2434 for (table t : instance.getTables()) { 2435 if (!SQLUtil.isTempTable(t)) { 2436 tables.add(t); 2437 } 2438 else { 2439 if (option.isIgnoreTemporaryTable()) { 2440 continue; 2441 } 2442 else { 2443 tables.add(t); 2444 } 2445 } 2446 } 2447 simple.setStages(instance.getStages()); 2448 simple.setSequences(instance.getSequences()); 2449 simple.setDatasources(instance.getDatasources()); 2450 simple.setStreams(instance.getStreams()); 2451 simple.setPaths(instance.getPaths()); 2452 simple.setTables(tables); 2453 simple.setViews(instance.getViews()); 2454 if(option.isSimpleShowVariable()) { 2455 simple.setVariables(instance.getVariables()); 2456 } 2457 else if(option.isSimpleShowCursor()) { 2458 simple.setVariables(instance.getVariables().stream().filter(t->SubType.cursor.name().equals(t.getSubType())).collect(Collectors.toList())); 2459 } 2460 if (instance.getResultsets() != null) { 2461 List<table> resultSets = new ArrayList<table>(); 2462 for (int i = 0; i < instance.getResultsets().size(); i++) { 2463 table resultSet = instance.getResultsets().get(i); 2464 if (isTargetResultSet(instance, resultSet.getId(), simpleOutput)) { 2465 // special handle function #524 #296 2466 resultSets.add(resultSet); 2467 } 2468 } 2469 simple.setResultsets(resultSets); 2470 } 2471 2472 List<table> functions = new ArrayList<table>(); 2473 if (option.isShowCallRelation()) { 2474 for (int i = 0; i < relations.size(); i++) { 2475 relationship relationElem = relations.get(i); 2476 if (!RelationshipType.call.name().equals(relationElem.getType())) { 2477 continue; 2478 } 2479 simpleRelations.add(relationElem); 2480 for (sourceColumn callee : relationElem.getCallees()) { 2481 String calleeId = callee.getId(); 2482 if (resultSetMap.containsKey(calleeId)) { 2483 table function = resultSetMap.get(calleeId); 2484 function.setIsTarget("true"); 2485 functions.add(function); 2486 } 2487 } 2488 } 2489 } 2490 2491 if (option.isShowERDiagram()) { 2492 for (int i = 0; i < relations.size(); i++) { 2493 relationship relationElem = relations.get(i); 2494 if (!RelationshipType.er.name().equals(relationElem.getType())) { 2495 continue; 2496 } 2497 simpleRelations.add(relationElem); 2498 for (sourceColumn callee : relationElem.getCallees()) { 2499 String calleeId = callee.getId(); 2500 if (resultSetMap.containsKey(calleeId)) { 2501 table function = resultSetMap.get(calleeId); 2502 function.setIsTarget("true"); 2503 functions.add(function); 2504 } 2505 } 2506 } 2507 } 2508 2509 if (!functions.isEmpty()) { 2510 if (simple.getResultsets() == null) { 2511 simple.setResultsets(functions); 2512 } else { 2513 simple.getResultsets().addAll(functions); 2514 } 2515 } 2516 2517 simple.setRelationships(simpleRelations); 2518 simple.setOrientation(instance.getOrientation()); 2519 targetTables.clear(); 2520 resultSetMap.clear(); 2521 tableMap.clear(); 2522 viewMap.clear(); 2523 cursorMap.clear(); 2524 variableMap.clear(); 2525 fileMap.clear(); 2526 stageMap.clear(); 2527 dataSourceMap.clear(); 2528 databaseMap.clear(); 2529 schemaMap.clear(); 2530 streamMap.clear(); 2531 return simple; 2532 } 2533 2534 private void findSourceRelations(targetColumn target, dataflow instance, Map<String, Set<relationship>> sourceIdRelationMap, 2535 relationship targetRelation, List<Pair<sourceColumn, List<String>>> relationSources, String[] pathTypes, boolean simpleOutput) { 2536 findStarSourceRelations(target, instance, null, sourceIdRelationMap, targetRelation, relationSources, pathTypes, 2537 new HashSet<String>(), new LinkedHashSet<transform>(), new LinkedHashSet<candidateTable>(), 0, simpleOutput); 2538 } 2539 2540 private void findStarSourceRelations(targetColumn target, dataflow instance, targetColumn starRelationTarget, 2541 Map<String, Set<relationship>> sourceIdRelationMap, relationship targetRelation, 2542 List<Pair<sourceColumn, List<String>>> relationSources, String[] pathTypes, Set<String> paths, 2543 Set<transform> transforms, Set<candidateTable> candidateTables, int level, boolean simpleOutput) { 2544 if (targetRelation != null && targetRelation.getSources() != null) { 2545 2546 //获取source为*的Column Parent 2547 String starParentId = null; 2548 for (int i = 0; i < targetRelation.getSources().size(); i++) { 2549 sourceColumn source = targetRelation.getSources().get(i); 2550 if (starRelationTarget != null && "*".equals(source.getColumn())) { 2551 starParentId = source.getParent_id(); 2552 } 2553 } 2554 2555 for (int i = 0; i < targetRelation.getSources().size(); i++) { 2556 sourceColumn source = targetRelation.getSources().get(i); 2557 if (starRelationTarget != null && !"*".equals(source.getColumn()) 2558 && !DlineageUtil.getIdentifierNormalColumnName(starRelationTarget.getColumn()) 2559 .equals(DlineageUtil.getIdentifierNormalColumnName(source.getColumn()))) { 2560 table parent = allMap.get(source.getParent_id()); 2561 if (parent != null && isFunction(parent)) { 2562 // function返回值未知,不对星号做处理 2563 } 2564 else if (parent == null) { 2565 continue; 2566 } else if(starParentId!=null && starParentId.equals(parent.getId())){ 2567 //如果source和 * column的parent相同,则跳过 2568 continue; 2569 } 2570 } 2571 2572 String sourceColumnId = source.getId(); 2573 String sourceParentId = source.getParent_id(); 2574 if (sourceParentId == null || sourceColumnId == null) { 2575 continue; 2576 } 2577 if (isTarget(instance, sourceParentId, simpleOutput)) { 2578 List<transform> transforms2 = new ArrayList<transform>(transforms.size()); 2579 transforms2.addAll(transforms); 2580 Collections.reverse(transforms2); 2581 2582 List<candidateTable> candidateTables2 = new ArrayList<candidateTable>(candidateTables.size()); 2583 candidateTables2.addAll(candidateTables); 2584 2585 sourceColumn sourceColumnCopy = DlineageUtil.copySourceColumn(source); 2586 for (transform t : transforms2) { 2587 sourceColumnCopy.addTransform(t); 2588 } 2589 2590 for (candidateTable t : candidateTables2) { 2591 sourceColumnCopy.addCandidateParent(t); 2592 } 2593 2594 if(Boolean.TRUE.equals(target.isStruct()) && Boolean.TRUE.equals(source.isStruct())) { 2595 List<String> targetColumns = SQLUtil.parseNames(target.getColumn()); 2596 List<String> sourceColumns = SQLUtil.parseNames(source.getColumn()); 2597 if(!DlineageUtil.getIdentifierNormalColumnName(targetColumns.get(targetColumns.size()-1)) 2598 .equals(DlineageUtil.getIdentifierNormalColumnName(sourceColumns.get(sourceColumns.size()-1)))) { 2599 continue; 2600 } 2601 } 2602 relationSources.add(new Pair<sourceColumn, List<String>>(sourceColumnCopy, Arrays.asList(pathTypes))); 2603 } else { 2604 Set<relationship> sourceRelations = sourceIdRelationMap 2605 .get(source.getParent_id() + "." + source.getId()); 2606 if (sourceRelations != null) { 2607 if (paths.contains(source.getParent_id() + "." + source.getId())) { 2608 continue; 2609 } else { 2610 paths.add(source.getParent_id() + "." + source.getId()); 2611 if (source.getTransforms() != null) { 2612 transforms.addAll(source.getTransforms()); 2613 } 2614 if (source.getCandidateParents() != null) { 2615 candidateTables.addAll(source.getCandidateParents()); 2616 } 2617 } 2618 for (relationship relation : sourceRelations) { 2619 LinkedHashSet<transform> transforms2 = new LinkedHashSet<transform>(transforms.size()); 2620 transforms2.addAll(transforms); 2621 LinkedHashSet<candidateTable> candidateTables2 = new LinkedHashSet<candidateTable>(candidateTables.size()); 2622 candidateTables2.addAll(candidateTables); 2623 String[] types = new String[pathTypes.length + 1]; 2624 types[0] = relation.getType(); 2625 System.arraycopy(pathTypes, 0, types, 1, pathTypes.length); 2626 if (!"*".equals(source.getColumn())) { 2627 findStarSourceRelations(target, instance, null, sourceIdRelationMap, relation, relationSources, 2628 types, paths, transforms2, candidateTables2, level + 1, simpleOutput); 2629 } else { 2630 findStarSourceRelations(target, instance, 2631 starRelationTarget == null ? targetRelation.getTarget() : starRelationTarget, 2632 sourceIdRelationMap, relation, relationSources, types, paths, transforms, candidateTables2, 2633 level + 1, simpleOutput); 2634 } 2635 } 2636 } 2637 } 2638 } 2639 } 2640 } 2641 2642 private Map<String, Boolean> targetTables = new HashMap<String, Boolean>(); 2643 private Map<String, table> resultSetMap = new HashMap<String, table>(); 2644 private Map<String, table> tableMap = new HashMap<String, table>(); 2645 private Map<String, table> viewMap = new HashMap<String, table>(); 2646 private Map<String, table> cursorMap = new HashMap<String, table>(); 2647 private Map<String, table> variableMap = new HashMap<String, table>(); 2648 private Map<String, table> fileMap = new HashMap<String, table>(); 2649 private Map<String, table> stageMap = new HashMap<String, table>(); 2650 private Map<String, table> sequenceMap = new HashMap<String, table>(); 2651 private Map<String, table> dataSourceMap = new HashMap<String, table>(); 2652 private Map<String, table> databaseMap = new HashMap<String, table>(); 2653 private Map<String, table> schemaMap = new HashMap<String, table>(); 2654 private Map<String, table> streamMap = new HashMap<String, table>(); 2655 private Map<String, table> allMap = new HashMap<String, table>(); 2656 2657 private boolean isTarget(dataflow instance, String targetParentId, boolean simpleOutput) { 2658 if (targetTables.containsKey(targetParentId)) 2659 return targetTables.get(targetParentId); 2660 if (isTable(instance, targetParentId)) { 2661 targetTables.put(targetParentId, true); 2662 return true; 2663 } else if (isView(instance, targetParentId)) { 2664 targetTables.put(targetParentId, true); 2665 return true; 2666 } else if (isFile(instance, targetParentId)) { 2667 targetTables.put(targetParentId, true); 2668 return true; 2669 } else if (isDatabase(instance, targetParentId)) { 2670 targetTables.put(targetParentId, true); 2671 return true; 2672 } else if (isSchema(instance, targetParentId)) { 2673 targetTables.put(targetParentId, true); 2674 return true; 2675 } else if (isStage(instance, targetParentId)) { 2676 targetTables.put(targetParentId, true); 2677 return true; 2678 } else if (isSequence(instance, targetParentId)) { 2679 targetTables.put(targetParentId, true); 2680 return true; 2681 } else if (isDataSource(instance, targetParentId)) { 2682 targetTables.put(targetParentId, true); 2683 return true; 2684 } else if (isStream(instance, targetParentId)) { 2685 targetTables.put(targetParentId, true); 2686 return true; 2687 } else if (isCursor(instance, targetParentId) && option.isSimpleShowCursor()) { 2688 targetTables.put(targetParentId, true); 2689 return true; 2690 } else if ((isVariable(instance, targetParentId) || isCursor(instance, targetParentId)) && option.isSimpleShowVariable()) { 2691 targetTables.put(targetParentId, true); 2692 return true; 2693 } else if (isTargetResultSet(instance, targetParentId, simpleOutput)) { 2694 targetTables.put(targetParentId, true); 2695 return true; 2696 } 2697 targetTables.put(targetParentId, false); 2698 return false; 2699 } 2700 2701 private boolean isTargetResultSet(dataflow instance, String targetParent, boolean simpleOutput) { 2702 if (resultSetMap.containsKey(targetParent.toLowerCase())) { 2703 table result = resultSetMap.get(targetParent.toLowerCase()); 2704 boolean isTarget = result.isTarget(); 2705 Option option = ModelBindingManager.getGlobalOption(); 2706 if (option != null && option.isSqlflowIgnoreFunction() && isFunction(result)) { 2707 return false; 2708 } 2709 if (isTarget && simpleOutput) { 2710 if (option != null && option.isSimpleShowFunction() && isFunction(result)) { 2711 return true; 2712 2713 } else if (option != null && option.isSimpleShowTopSelectResultSet()) { 2714 return true; 2715 } 2716 if (ResultSetType.of(result.getType()) != null && option.containsResultSetType(ResultSetType.of(result.getType()))) { 2717 return true; 2718 } 2719 } else 2720 return isTarget; 2721 } 2722 return false; 2723 } 2724 2725 private boolean isFunction(table resultSet) { 2726 if("function".equals(resultSet.getType())){ 2727 return true; 2728 } 2729 else if("resultset".equals(resultSet.getType()) && "function".equals(resultSet.getSubType())){ 2730 return true; 2731 } 2732 return false; 2733 } 2734 2735 private boolean isView(dataflow instance, String targetParent) { 2736 if (viewMap.containsKey(targetParent.toLowerCase())) { 2737 return true; 2738 } 2739 return false; 2740 } 2741 2742 private boolean isCursor(dataflow instance, String targetParent) { 2743 if (cursorMap.containsKey(targetParent.toLowerCase())) { 2744 return true; 2745 } 2746 return false; 2747 } 2748 2749 private boolean isVariable(dataflow instance, String targetParent) { 2750 if (variableMap.containsKey(targetParent.toLowerCase())) { 2751 return true; 2752 } 2753 return false; 2754 } 2755 2756 private boolean isFile(dataflow instance, String targetParent) { 2757 if (fileMap.containsKey(targetParent.toLowerCase())) { 2758 return true; 2759 } 2760 return false; 2761 } 2762 2763 private boolean isStage(dataflow instance, String targetParent) { 2764 if (stageMap.containsKey(targetParent.toLowerCase())) { 2765 return true; 2766 } 2767 return false; 2768 } 2769 2770 private boolean isSequence(dataflow instance, String targetParent) { 2771 if (sequenceMap.containsKey(targetParent.toLowerCase())) { 2772 return true; 2773 } 2774 return false; 2775 } 2776 2777 private boolean isDataSource(dataflow instance, String targetParent) { 2778 if (dataSourceMap.containsKey(targetParent.toLowerCase())) { 2779 return true; 2780 } 2781 return false; 2782 } 2783 2784 private boolean isDatabase(dataflow instance, String targetParent) { 2785 if (databaseMap.containsKey(targetParent.toLowerCase())) { 2786 return true; 2787 } 2788 return false; 2789 } 2790 2791 private boolean isSchema(dataflow instance, String targetParent) { 2792 if (schemaMap.containsKey(targetParent.toLowerCase())) { 2793 return true; 2794 } 2795 return false; 2796 } 2797 2798 private boolean isStream(dataflow instance, String targetParent) { 2799 if (streamMap.containsKey(targetParent.toLowerCase())) { 2800 return true; 2801 } 2802 return false; 2803 } 2804 2805 private boolean isTable(dataflow instance, String targetParent) { 2806 if (tableMap.containsKey(targetParent.toLowerCase())) { 2807 if (SQLUtil.isTempTable(tableMap.get(targetParent))) { 2808 if (option.isIgnoreTemporaryTable()) { 2809 return false; 2810 } 2811 } 2812 if (tableMap.get(targetParent).isFunction()) { 2813 if (option != null && option.isSimpleShowFunction()) { 2814 return true; 2815 } else { 2816 return false; 2817 } 2818 } 2819 if (SubType.synonym.name().equals(tableMap.get(targetParent).getSubType())) { 2820 if (option != null && option.isSimpleShowSynonym()) { 2821 return true; 2822 } else { 2823 return false; 2824 } 2825 } 2826 return true; 2827 } else { 2828 return false; 2829 } 2830 } 2831 2832 private void init() { 2833 metadataErrors.clear(); 2834 sqlInfoMap.clear(); 2835 errorInfos.clear(); 2836 dynamicSqlSites.clear(); 2837 dataflow = null; 2838 dataflowString = null; 2839 ModelBindingManager.removeGlobalDatabase(); 2840 ModelBindingManager.removeGlobalSchema(); 2841 ModelBindingManager.removeGlobalVendor(); 2842 ModelBindingManager.removeGlobalSQLEnv(); 2843 ModelBindingManager.removeGlobalHash(); 2844 appendResultSets.clear(); 2845 appendStarColumns.clear(); 2846 appendTableStarColumns.clear(); 2847 modelManager.TABLE_COLUMN_ID = option.getStartId(); 2848 modelManager.RELATION_ID = option.getStartId(); 2849 modelManager.DISPLAY_ID.clear(); 2850 modelManager.DISPLAY_NAME.clear(); 2851 tableIds.clear(); 2852 ModelBindingManager.setGlobalVendor(option.getVendor()); 2853 modelManager.reset(); 2854 } 2855 2856 private String getErrorMessage(TSyntaxError error, String errorType) { 2857 String s = "", hint = "Syntax error"; 2858 if (ErrorInfo.SYNTAX_HINT.equals(errorType)) { 2859 hint = "Syntax hint"; 2860 } 2861 if (error.hint.length() > 0) 2862 hint = error.hint; 2863 s = s + hint + "(" + error.errorno + ") near: " + error.tokentext; 2864 s = s + "(" + error.lineNo; 2865 s = s + "," + error.columnNo + ")"; 2866 return s; 2867 } 2868 2869// boolean OLD_ENABLE_RESOLVER = TBaseType.isEnableResolver(); 2870 private void analyzeAndOutputResult(TGSqlParser sqlparser) { 2871 try { 2872 accessedSubqueries.clear(); 2873 accessedStatements.clear(); 2874 stmtStack.clear(); 2875 viewDDLMap.clear(); 2876 procedureDDLMap.clear(); 2877 structObjectMap.clear(); 2878 try { 2879 if(sqlenv!=null) { 2880 sqlparser.setSqlEnv(sqlenv); 2881 } 2882 int result = sqlparser.parse(); 2883 if (result != 0) { 2884 ArrayList<TSyntaxError> errors = sqlparser.getSyntaxErrors(); 2885 if (errors != null && !errors.isEmpty()) { 2886 for (int i = 0; i < errors.size(); i++) { 2887 TSyntaxError error = errors.get(i); 2888 ErrorInfo errorInfo = new ErrorInfo(); 2889 errorInfo.setErrorType(ErrorInfo.SYNTAX_ERROR); 2890 errorInfo.setErrorMessage(getErrorMessage(error, ErrorInfo.SYNTAX_ERROR)); 2891 errorInfo.setStartPosition(new Pair3<Long, Long, String>(error.lineNo, error.columnNo, 2892 ModelBindingManager.getGlobalHash())); 2893 String[] segments = error.tokentext.split("\n"); 2894 if (segments.length <= 1) { 2895 errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo, 2896 error.columnNo + error.tokentext.length(), 2897 ModelBindingManager.getGlobalHash())); 2898 } else { 2899 errorInfo.setEndPosition( 2900 new Pair3<Long, Long, String>(error.lineNo + segments.length - 1, 2901 (long) segments[segments.length - 1].length() + 1, 2902 ModelBindingManager.getGlobalHash())); 2903 } 2904 ; 2905 errorInfo.fillInfo(this); 2906 errorInfos.add(errorInfo); 2907 } 2908 } 2909 } 2910 2911 if (option.getHandleListener() != null) { 2912 option.getHandleListener().endParse(result == 0); 2913 } 2914 } catch (Exception e) { 2915 logger.error("analyze sql failed.", e); 2916 if (option.getHandleListener() != null) { 2917 option.getHandleListener().endParse(false); 2918 } 2919 ErrorInfo errorInfo = new ErrorInfo(); 2920 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 2921 if (e.getMessage() == null) { 2922 if (e.getStackTrace() != null && e.getStackTrace().length > 0) { 2923 errorInfo 2924 .setErrorMessage(e.getClass().getSimpleName() + ": " + e.getStackTrace()[0].toString()); 2925 } else { 2926 errorInfo.setErrorMessage(e.getClass().getSimpleName()); 2927 } 2928 } else { 2929 errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getMessage()); 2930 } 2931 errorInfo.fillInfo(this); 2932 errorInfos.add(errorInfo); 2933 return; 2934 } 2935 2936 2937 TSQLResolver2 resolver = sqlparser.getResolver2(); 2938 if (resolver != null && option.getVendor() == EDbVendor.dbvbigquery) { 2939 ScopeBuildResult buildResult = resolver.getScopeBuildResult(); 2940 List<TObjectName> columns = buildResult.getAllColumnReferences(); 2941 for (TObjectName col : columns) { 2942 structObjectMap.putIfAbsent(col.getSourceTable(), new TObjectNameList()); 2943 structObjectMap.get(col.getSourceTable()).addObjectName(col); 2944 } 2945 } 2946 2947 if (option.getHandleListener() != null) { 2948 option.getHandleListener().startAnalyzeDataFlow(sqlparser); 2949 } 2950 2951 for (int i = 0; i < sqlparser.getSqlstatements().size(); i++) { 2952 if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) { 2953 break; 2954 } 2955 2956 TCustomSqlStatement stmt = sqlparser.getSqlstatements().get(i); 2957 if (stmt.getErrorCount() == 0) { 2958 if (stmt.getParentStmt() == null) { 2959 modelManager.collectSqlHash(stmt); 2960 if (stmt instanceof TUseDatabase || stmt instanceof TUseSchema 2961 || stmt instanceof TCreateTableSqlStatement 2962 || stmt instanceof TCreateExternalDataSourceStmt || stmt instanceof TCreateStageStmt 2963 || stmt instanceof TMssqlCreateType 2964 || stmt instanceof TMssqlDeclare 2965 || stmt instanceof TPlsqlCreateType_Placeholder 2966 || stmt instanceof TPlsqlCreateType 2967 || stmt instanceof TPlsqlTableTypeDefStmt 2968 || (stmt instanceof TCreateFunctionStmt && hasDb2ReturnStmt((TCreateFunctionStmt)stmt)) 2969 || (stmt instanceof TMssqlCreateFunction 2970 && (((TMssqlCreateFunction) stmt).getReturnTableDefinitions() != null 2971 || ((TMssqlCreateFunction) stmt).getReturnStmt() != null))) { 2972 boolean listen = false; 2973 if (option.getHandleListener() != null && !accessedStatements.contains(stmt)) { 2974 option.getHandleListener().startAnalyzeStatment(stmt); 2975 listen = true; 2976 } 2977 analyzeCustomSqlStmt(stmt); 2978 if (listen && option.getHandleListener() != null) { 2979 option.getHandleListener().endAnalyzeStatment(stmt); 2980 } 2981 } 2982 } 2983 } 2984 } 2985 2986 for (int i = 0; i < sqlparser.sqlstatements.size(); i++) { 2987 if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) { 2988 break; 2989 } 2990 2991 TCustomSqlStatement stmt = sqlparser.getSqlstatements().get(i); 2992 if (stmt.getErrorCount() == 0) { 2993 if (stmt.getParentStmt() == null) { 2994 if (stmt instanceof TUseDatabase 2995 || stmt instanceof TUseSchema 2996 || stmt instanceof TCreateViewSqlStatement 2997 || stmt instanceof TCreateSynonymStmt 2998 || stmt instanceof TStoredProcedureSqlStatement) { 2999 boolean listen = false; 3000 if (option.getHandleListener() != null && !accessedStatements.contains(stmt)) { 3001 option.getHandleListener().startAnalyzeStatment(stmt); 3002 listen = true; 3003 } 3004 if (stmt instanceof TUseDatabase || stmt instanceof TUseSchema) { 3005 analyzeCustomSqlStmt(stmt); 3006 } else if (stmt instanceof TCreateViewSqlStatement) { 3007 TCreateViewSqlStatement view = (TCreateViewSqlStatement) stmt; 3008 if(view.getViewName()!=null) { 3009 viewDDLMap.put(DlineageUtil.getTableFullName(view.getViewName().toString()), view); 3010 } 3011 } else if (stmt instanceof TCreateSynonymStmt) { 3012 TCreateSynonymStmt synonym = (TCreateSynonymStmt) stmt; 3013 if(synonym.getSynonymName()!=null) { 3014 viewDDLMap.put(DlineageUtil.getTableFullName(synonym.getSynonymName().toString()), synonym); 3015 } 3016 } else if (stmt instanceof TStoredProcedureSqlStatement) { 3017 TStoredProcedureSqlStatement procedure = (TStoredProcedureSqlStatement) stmt; 3018 if(procedure.getStoredProcedureName() == null) { 3019 continue; 3020 } 3021 procedureDDLMap.put(DlineageUtil.getProcedureNameWithArgNum(procedure), procedure); 3022 } 3023 if (listen && option.getHandleListener() != null) { 3024 option.getHandleListener().endAnalyzeStatment(stmt); 3025 } 3026 } 3027 } 3028 } 3029 } 3030 3031 for (int i = 0; i < sqlparser.sqlstatements.size(); i++) { 3032 if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) { 3033 break; 3034 } 3035 3036 TCustomSqlStatement stmt = sqlparser.getSqlstatements().get(i); 3037 if (stmt.getErrorCount() == 0) { 3038 if (stmt.getParentStmt() == null) { 3039 if (stmt instanceof TUseDatabase 3040 || stmt instanceof TUseSchema 3041 || stmt instanceof TCreateViewSqlStatement 3042 || stmt instanceof TCreateSynonymStmt) { 3043 boolean listen = false; 3044 if (option.getHandleListener() != null && !accessedStatements.contains(stmt)) { 3045 option.getHandleListener().startAnalyzeStatment(stmt); 3046 listen = true; 3047 } 3048 analyzeCustomSqlStmt(stmt); 3049 if (listen && option.getHandleListener() != null) { 3050 option.getHandleListener().endAnalyzeStatment(stmt); 3051 } 3052 } 3053 } 3054 } 3055 } 3056 3057 for (int i = 0; i < sqlparser.sqlstatements.size(); i++) { 3058 if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) { 3059 break; 3060 } 3061 3062 TCustomSqlStatement stmt = sqlparser.getSqlstatements().get(i); 3063 if (stmt.getErrorCount() == 0) { 3064 if (stmt.getParentStmt() == null) { 3065 if (stmt instanceof TUseDatabase || stmt instanceof TUseSchema 3066 || stmt instanceof TStoredProcedureSqlStatement) { 3067 boolean listen = false; 3068 if (option.getHandleListener() != null && !accessedStatements.contains(stmt)) { 3069 option.getHandleListener().startAnalyzeStatment(stmt); 3070 listen = true; 3071 } 3072 if (stmt instanceof TPlsqlCreateTrigger) 3073 continue; 3074 analyzeCustomSqlStmt(stmt); 3075 if (listen && option.getHandleListener() != null) { 3076 option.getHandleListener().endAnalyzeStatment(stmt); 3077 } 3078 } 3079 } 3080 } 3081 } 3082 3083 for (int i = 0; i < sqlparser.sqlstatements.size(); i++) { 3084 if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) { 3085 break; 3086 } 3087 3088 TCustomSqlStatement stmt = sqlparser.getSqlstatements().get(i); 3089 3090 if (option.isIgnoreTopSelect()) { 3091 if ((stmt instanceof TSelectSqlStatement && ((TSelectSqlStatement)stmt).getIntoClause() == null && ((TSelectSqlStatement)stmt).getIntoTableClause() == null ) || stmt instanceof TRedshiftDeclare 3092 || stmt instanceof TRedshiftDeclare) { 3093 continue; 3094 } 3095 } 3096 3097 if (stmt.getErrorCount() == 0) { 3098 if (stmt.getParentStmt() == null) { 3099 if (!(stmt instanceof TCreateViewSqlStatement) && !(stmt instanceof TCreateStageStmt) 3100 && !(stmt instanceof TCreateExternalDataSourceStmt) 3101 && !(stmt instanceof TCreateViewSqlStatement) && !(stmt instanceof TMssqlDeclare) 3102 && !(stmt instanceof TMssqlCreateFunction 3103 && ((TMssqlCreateFunction) stmt).getReturnTableDefinitions() != null)) { 3104 boolean listen = false; 3105 if (option.getHandleListener() != null && !accessedStatements.contains(stmt)) { 3106 option.getHandleListener().startAnalyzeStatment(stmt); 3107 listen = true; 3108 } 3109 analyzeCustomSqlStmt(stmt); 3110 if (listen && option.getHandleListener() != null) { 3111 option.getHandleListener().endAnalyzeStatment(stmt); 3112 } 3113 } 3114 } 3115 } 3116 } 3117 3118 if (option.getHandleListener() != null) { 3119 option.getHandleListener().endAnalyzeDataFlow(sqlparser); 3120 } 3121 3122 // Finalize pipelined function stitching after all passes 3123 if (!modelManager.getPendingPipelinedCallSites().isEmpty() && sqlparser.getSqlstatements().size() > 0 && pipelinedAnalyzer != null) { 3124 TCustomSqlStatement lastStmt = sqlparser.getSqlstatements().get(sqlparser.getSqlstatements().size() - 1); 3125 stmtStack.push(lastStmt); 3126 try { 3127 pipelinedAnalyzer.stitchPendingCallSites(); 3128 } catch (Exception ex) { 3129 // Don't let pipelined stitching failure break main flow 3130 } finally { 3131 stmtStack.pop(); 3132 } 3133 } 3134 } catch (Throwable e) { 3135 logger.error("analyze sql failed.", e); 3136 ErrorInfo errorInfo = new ErrorInfo(); 3137 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 3138 if (e.getMessage() == null) { 3139 if (e.getStackTrace() != null && e.getStackTrace().length > 0) { 3140 errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getStackTrace()[0].toString()); 3141 } else { 3142 errorInfo.setErrorMessage(e.getClass().getSimpleName()); 3143 } 3144 } else { 3145 errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getMessage()); 3146 } 3147 errorInfo.fillInfo(this); 3148 errorInfos.add(errorInfo); 3149 } 3150 3151 } 3152 3153 private boolean hasDb2ReturnStmt(TCreateFunctionStmt stmt) { 3154 if (stmt.getReturnStmt() != null) { 3155 return true; 3156 } 3157 if (stmt.getBodyStatements() != null) { 3158 for (int i = 0; i < stmt.getBodyStatements().size(); i++) { 3159 if(stmt.getBodyStatements().get(i) instanceof TDb2ReturnStmt) { 3160 return true; 3161 } 3162 } 3163 } 3164 return false; 3165 } 3166 3167 private void analyzeCustomSqlStmt(TCustomSqlStatement stmt) { 3168 if (!accessedStatements.contains(stmt)) { 3169 accessedStatements.add(stmt); 3170 } else if (!(stmt instanceof TUseDatabase || stmt instanceof TUseSchema)) { 3171 return; 3172 } 3173 3174 ArrayList<TSyntaxError> errors = stmt.getSyntaxHints(); 3175 if (errors != null && !errors.isEmpty()) { 3176 for (int i = 0; i < errors.size(); i++) { 3177 TSyntaxError error = errors.get(i); 3178 ErrorInfo errorInfo = new ErrorInfo(); 3179 errorInfo.setErrorType(ErrorInfo.SYNTAX_HINT); 3180 errorInfo.setErrorMessage(getErrorMessage(error, ErrorInfo.SYNTAX_HINT)); 3181 errorInfo.setStartPosition(new Pair3<Long, Long, String>(error.lineNo, error.columnNo, 3182 ModelBindingManager.getGlobalHash())); 3183 String[] segments = error.tokentext.split("\n"); 3184 if (segments.length == 1) { 3185 errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo, 3186 error.columnNo + error.tokentext.length(), ModelBindingManager.getGlobalHash())); 3187 } else { 3188 errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo + segments.length - 1, 3189 (long) segments[segments.length - 1].length() + 1, ModelBindingManager.getGlobalHash())); 3190 } 3191 errorInfo.fillInfo(this); 3192 errorInfos.add(errorInfo); 3193 } 3194 } 3195 3196 if (option.getAnalyzeMode() == AnalyzeMode.dynamic) { 3197 if (!(stmt instanceof TStoredProcedureSqlStatement 3198 || stmt instanceof TExecuteSqlStatement 3199 || stmt instanceof TMssqlExecute 3200 || stmt instanceof TExecImmeStmt)) { 3201 return; 3202 } 3203 } 3204 3205 if(DlineageUtil.getTopStmt(stmt) == stmt){ 3206 modelManager.collectSqlHash(stmt); 3207 } 3208 3209 try { 3210 if (stmt instanceof TUseDatabase) { 3211 if (((TUseDatabase) stmt).getDatabaseName() != null) { 3212 ModelBindingManager.setGlobalDatabase(((TUseDatabase) stmt).getDatabaseName().toString()); 3213 } 3214 } else if (stmt instanceof TUseSchema) { 3215 if (((TUseSchema) stmt).getSchemaName() != null) { 3216 String schemaName = ((TUseSchema) stmt).getSchemaName().toString(); 3217 List<String> splits = SQLUtil.parseNames(schemaName); 3218 if (splits.size() == 1) { 3219 ModelBindingManager.setGlobalSchema(schemaName); 3220 } else if (splits.size() > 1) { 3221 ModelBindingManager.setGlobalSchema(splits.get(splits.size() - 1)); 3222 ModelBindingManager.setGlobalDatabase(splits.get(splits.size() - 2)); 3223 } 3224 } 3225 } else if (stmt instanceof TPlsqlRecordTypeDefStmt) { 3226 this.stmtStack.push(stmt); 3227 this.analyzePlsqlRecordTypeDefStmt((TPlsqlRecordTypeDefStmt) stmt); 3228 this.stmtStack.pop(); 3229 } else if (stmt instanceof TPlsqlCreateType_Placeholder) { 3230 this.stmtStack.push(stmt); 3231 TPlsqlCreateType_Placeholder placeholder = (TPlsqlCreateType_Placeholder) stmt; 3232 if (placeholder.getObjectStatement() != null && pipelinedAnalyzer != null) { 3233 this.pipelinedAnalyzer.indexObjectType(placeholder.getObjectStatement()); 3234 } 3235 if (placeholder.getNestedTableStatement() != null) { 3236 if (pipelinedAnalyzer != null) { 3237 this.pipelinedAnalyzer.indexCollectionType(placeholder.getNestedTableStatement()); 3238 } 3239 this.analyzePlsqlTableTypeDefStmt(placeholder.getNestedTableStatement()); 3240 } 3241 this.stmtStack.pop(); 3242 } else if (stmt instanceof TPlsqlCreateType) { 3243 this.stmtStack.push(stmt); 3244 if (pipelinedAnalyzer != null) { 3245 this.pipelinedAnalyzer.indexObjectType((TPlsqlCreateType) stmt); 3246 } 3247 this.stmtStack.pop(); 3248 } else if (stmt instanceof TPlsqlTableTypeDefStmt) { 3249 this.stmtStack.push(stmt); 3250 this.analyzePlsqlTableTypeDefStmt((TPlsqlTableTypeDefStmt) stmt); 3251 if (pipelinedAnalyzer != null) { 3252 this.pipelinedAnalyzer.indexCollectionType((TPlsqlTableTypeDefStmt) stmt); 3253 } 3254 this.stmtStack.pop(); 3255 } else if (stmt instanceof TStoredProcedureSqlStatement) { 3256 this.stmtStack.push(stmt); 3257 this.analyzeStoredProcedureStmt((TStoredProcedureSqlStatement) stmt); 3258 this.stmtStack.pop(); 3259 } else if (stmt instanceof TCreateTableSqlStatement) { 3260 stmtStack.push(stmt); 3261 analyzeCreateTableStmt((TCreateTableSqlStatement) stmt); 3262 stmtStack.pop(); 3263 } else if (stmt instanceof TCreateStageStmt) { 3264 stmtStack.push(stmt); 3265 analyzeCreateStageStmt((TCreateStageStmt) stmt); 3266 stmtStack.pop(); 3267 } else if (stmt instanceof TCreateExternalDataSourceStmt) { 3268 stmtStack.push(stmt); 3269 analyzeCreateExternalDataSourceStmt((TCreateExternalDataSourceStmt) stmt); 3270 stmtStack.pop(); 3271 } else if (stmt instanceof TCreateStreamStmt) { 3272 stmtStack.push(stmt); 3273 analyzeCreateStreamStmt((TCreateStreamStmt) stmt); 3274 stmtStack.pop(); 3275 } else if (stmt instanceof TSelectSqlStatement) { 3276 analyzeSelectStmt((TSelectSqlStatement) stmt); 3277 } else if (stmt instanceof TDropTableSqlStatement) { 3278 stmtStack.push(stmt); 3279 analyzeDropTableStmt((TDropTableSqlStatement) stmt); 3280 stmtStack.pop(); 3281 } else if (stmt instanceof TTruncateStatement) { 3282 stmtStack.push(stmt); 3283 analyzeTruncateTableStmt((TTruncateStatement) stmt); 3284 stmtStack.pop(); 3285 } else if (stmt instanceof TCreateMaterializedSqlStatement) { 3286 stmtStack.push(stmt); 3287 TCreateMaterializedSqlStatement view = (TCreateMaterializedSqlStatement) stmt; 3288 analyzeCreateViewStmt(view, view.getSubquery(), view.getViewAliasClause(), view.getViewName()); 3289 stmtStack.pop(); 3290 } else if (stmt instanceof TCreateViewSqlStatement) { 3291 stmtStack.push(stmt); 3292 TCreateViewSqlStatement view = (TCreateViewSqlStatement) stmt; 3293 analyzeCreateViewStmt(view, view.getSubquery(), view.getViewAliasClause(), view.getViewName()); 3294 stmtStack.pop(); 3295 } else if(stmt instanceof TDb2SqlVariableDeclaration){ 3296 stmtStack.push(stmt); 3297 analyzeDb2Declare((TDb2SqlVariableDeclaration)stmt); 3298 stmtStack.pop(); 3299 } else if (stmt instanceof TMssqlCreateType) { 3300 stmtStack.push(stmt); 3301 TMssqlCreateType createType = (TMssqlCreateType) stmt; 3302 analyzeMssqlCreateType(createType); 3303 stmtStack.pop(); 3304 } else if (stmt instanceof TMssqlDeclare) { 3305 stmtStack.push(stmt); 3306 TMssqlDeclare declare = (TMssqlDeclare) stmt; 3307 analyzeMssqlDeclare(declare); 3308 stmtStack.pop(); 3309 } else if (stmt instanceof TInsertSqlStatement) { 3310 stmtStack.push(stmt); 3311 TInsertSqlStatement insert = (TInsertSqlStatement)stmt; 3312 analyzeInsertStmt(insert); 3313 if(insert.getMultiInsertStatements()!=null) { 3314 for(int i=0;i<insert.getMultiInsertStatements().size();i++) { 3315 analyzeInsertStmt(insert.getMultiInsertStatements().get(i)); 3316 } 3317 } 3318 stmtStack.pop(); 3319 } else if (stmt instanceof TRedshiftCopy) { 3320 stmtStack.push(stmt); 3321 analyzeRedshiftCopyStmt((TRedshiftCopy) stmt); 3322 stmtStack.pop(); 3323 } else if (stmt instanceof TSnowflakeCopyIntoStmt) { 3324 stmtStack.push(stmt); 3325 analyzeCopyIntoStmt((TSnowflakeCopyIntoStmt) stmt); 3326 stmtStack.pop(); 3327 } else if (stmt instanceof TUnloadStmt) { 3328 stmtStack.push(stmt); 3329 analyzeUnloadStmt((TUnloadStmt) stmt); 3330 stmtStack.pop(); 3331 } else if (stmt instanceof TUpdateSqlStatement) { 3332 stmtStack.push(stmt); 3333 analyzeUpdateStmt((TUpdateSqlStatement) stmt); 3334 stmtStack.pop(); 3335 } else if (stmt instanceof TMergeSqlStatement) { 3336 stmtStack.push(stmt); 3337 analyzeMergeStmt((TMergeSqlStatement) stmt); 3338 stmtStack.pop(); 3339 } else if (stmt instanceof TDeleteSqlStatement) { 3340 stmtStack.push(stmt); 3341 analyzeDeleteStmt((TDeleteSqlStatement) stmt); 3342 stmtStack.pop(); 3343 } else if (stmt instanceof TCursorDeclStmt) { 3344 stmtStack.push(stmt); 3345 analyzeCursorDeclStmt((TCursorDeclStmt) stmt); 3346 stmtStack.pop(); 3347 } else if (stmt instanceof TFetchStmt) { 3348 stmtStack.push(stmt); 3349 analyzeFetchStmt((TFetchStmt) stmt); 3350 stmtStack.pop(); 3351 } else if (stmt instanceof TMssqlFetch) { 3352 stmtStack.push(stmt); 3353 analyzeFetchStmt((TMssqlFetch) stmt); 3354 stmtStack.pop(); 3355 } else if (stmt instanceof TForStmt) { 3356 stmtStack.push(stmt); 3357 analyzeForStmt((TForStmt) stmt); 3358 stmtStack.pop(); 3359 } else if (stmt instanceof TOpenforStmt) { 3360 stmtStack.push(stmt); 3361 analyzeOpenForStmt((TOpenforStmt) stmt); 3362 stmtStack.pop(); 3363 } else if (stmt instanceof TLoopStmt) { 3364 stmtStack.push(stmt); 3365 analyzeLoopStmt((TLoopStmt) stmt); 3366 stmtStack.pop(); 3367 } else if (stmt instanceof TAssignStmt) { 3368 stmtStack.push(stmt); 3369 analyzeAssignStmt((TAssignStmt) stmt); 3370 stmtStack.pop(); 3371 } else if (stmt instanceof TSetStmt) { 3372 stmtStack.push(stmt); 3373 analyzeSetStmt((TSetStmt) stmt); 3374 stmtStack.pop(); 3375 } else if (stmt instanceof TMssqlSet) { 3376 stmtStack.push(stmt); 3377 analyzeMssqlSetStmt((TMssqlSet) stmt); 3378 stmtStack.pop(); 3379 } else if (stmt instanceof TVarDeclStmt) { 3380 stmtStack.push(stmt); 3381 analyzeVarDeclStmt((TVarDeclStmt) stmt); 3382 stmtStack.pop(); 3383 } else if (stmt instanceof TCreateDatabaseSqlStatement) { 3384 stmtStack.push(stmt); 3385 analyzeCloneDatabaseStmt((TCreateDatabaseSqlStatement) stmt); 3386 stmtStack.pop(); 3387 } else if (stmt instanceof TCreateSchemaSqlStatement) { 3388 stmtStack.push(stmt); 3389 analyzeCloneSchemaStmt((TCreateSchemaSqlStatement) stmt); 3390 stmtStack.pop(); 3391 } else if (stmt instanceof TAlterTableStatement) { 3392 stmtStack.push(stmt); 3393 analyzeAlterTableStmt((TAlterTableStatement) stmt); 3394 stmtStack.pop(); 3395 } else if (stmt instanceof TAlterViewStatement) { 3396 stmtStack.push(stmt); 3397 analyzeAlterViewStmt((TAlterViewStatement) stmt); 3398 stmtStack.pop(); 3399 } else if (stmt instanceof TRenameStmt) { 3400 stmtStack.push(stmt); 3401 analyzeRenameStmt((TRenameStmt) stmt); 3402 stmtStack.pop(); 3403 } else if (stmt instanceof TCreateSynonymStmt) { 3404 stmtStack.push(stmt); 3405 analyzeCreateSynonymStmt((TCreateSynonymStmt) stmt); 3406 stmtStack.pop(); 3407 } else if (stmt instanceof TLoadDataStmt) { 3408 stmtStack.push(stmt); 3409 analyzeLoadDataStmt((TLoadDataStmt) stmt); 3410 stmtStack.pop(); 3411 } else if (stmt instanceof THiveLoad) { 3412 stmtStack.push(stmt); 3413 analyzeHiveLoadStmt((THiveLoad) stmt); 3414 stmtStack.pop(); 3415 } else if (stmt instanceof TDb2ReturnStmt) { 3416 stmtStack.push(stmt); 3417 analyzeDb2ReturnStmt((TDb2ReturnStmt) stmt); 3418 stmtStack.pop(); 3419 } else if (stmt instanceof TReturnStmt) { 3420 stmtStack.push(stmt); 3421 analyzeReturnStmt((TReturnStmt) stmt); 3422 stmtStack.pop(); 3423 } else if (stmt instanceof TMssqlReturn) { 3424 stmtStack.push(stmt); 3425 analyzeMssqlReturnStmt((TMssqlReturn) stmt); 3426 stmtStack.pop(); 3427 } else if (stmt instanceof TExecuteSqlStatement) { 3428 String sqlText = ((TExecuteSqlStatement) stmt).getPreparedSqlText(); 3429 if(sqlText == null) { 3430 sqlText = ((TExecuteSqlStatement) stmt).getSqlText(); 3431 } 3432 if (sqlText != null) { 3433 modelManager.collectDynamicSqlHash(stmt); 3434 TGSqlParser sqlparser = new TGSqlParser(option.getVendor()); 3435 sqlparser.sqltext = SQLUtil.trimColumnStringQuote(sqlText); 3436 int result = sqlparser.parse(); 3437 if (result != 0) { 3438 errors = sqlparser.getSyntaxErrors(); 3439 if (errors != null && !errors.isEmpty()) { 3440 for (int i = 0; i < errors.size(); i++) { 3441 TSyntaxError error = errors.get(i); 3442 ErrorInfo errorInfo = new ErrorInfo(); 3443 errorInfo.setErrorType(ErrorInfo.SYNTAX_ERROR); 3444 errorInfo.setErrorMessage(getErrorMessage(error, ErrorInfo.SYNTAX_ERROR)); 3445 errorInfo.setStartPosition(new Pair3<Long, Long, String>(error.lineNo, error.columnNo, 3446 ModelBindingManager.getGlobalHash())); 3447 String[] segments = error.tokentext.split("\n"); 3448 if (segments.length == 1) { 3449 errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo, 3450 error.columnNo + error.tokentext.length(), 3451 ModelBindingManager.getGlobalHash())); 3452 } else { 3453 errorInfo.setEndPosition( 3454 new Pair3<Long, Long, String>(error.lineNo + segments.length - 1, 3455 (long) segments[segments.length - 1].length() + 1, 3456 ModelBindingManager.getGlobalHash())); 3457 } 3458 errorInfo.fillInfo(this); 3459 errorInfos.add(errorInfo); 3460 } 3461 } 3462 } else if (sqlparser.sqlstatements != null) { 3463 for (int i = 0; i < sqlparser.sqlstatements.size(); i++) { 3464 analyzeCustomSqlStmt(sqlparser.sqlstatements.get(i)); 3465 } 3466 } 3467 } 3468 else if (((TExecuteSqlStatement) stmt).getStmtString() != null) { 3469 modelManager.collectDynamicSqlHash(stmt); 3470 } 3471 } else if (stmt instanceof TMssqlExecute) { 3472 TMssqlExecute executeStmt = (TMssqlExecute)stmt; 3473 if (executeStmt.getSqlText() != null) { 3474 modelManager.collectDynamicSqlHash(stmt); 3475 TGSqlParser sqlparser = new TGSqlParser(option.getVendor()); 3476 sqlparser.sqltext = ((TMssqlExecute) stmt).getSqlText(); 3477 int relsBeforeDynamic = modelManager.getRelations().length; 3478 // A data-driven argument (variable / expression) is at most PARTIALLY folded: 3479 // GSP keeps the literal pieces but drops the unresolved trailing @var, leaving a 3480 // legitimately truncated fragment (e.g. "... WHERE " with no predicate -> end of 3481 // input). A parse failure on such text says nothing about the real SQL, so we must 3482 // not surface it as a unit SYNTAX_ERROR — that would discard the whole procedure's 3483 // lineage even though the outer parse succeeded. Only a true compile-time literal 3484 // EXEC('...') surfaces inner parse failures (mirrors the EXECUTE IMMEDIATE 3485 // isDynamicSQLPartial() guard below). 3486 boolean literalArg = isLiteralDynamicArg(executeStmt); 3487 int result = sqlparser.parse(); 3488 if (result != 0) { 3489 errors = literalArg ? sqlparser.getSyntaxErrors() : null; 3490 if (errors != null && !errors.isEmpty()) { 3491 for (int i = 0; i < errors.size(); i++) { 3492 TSyntaxError error = errors.get(i); 3493 ErrorInfo errorInfo = new ErrorInfo(); 3494 errorInfo.setErrorType(ErrorInfo.SYNTAX_ERROR); 3495 errorInfo.setErrorMessage(getErrorMessage(error, ErrorInfo.SYNTAX_ERROR)); 3496 errorInfo.setStartPosition(new Pair3<Long, Long, String>(error.lineNo, error.columnNo, 3497 ModelBindingManager.getGlobalHash())); 3498 String[] segments = error.tokentext.split("\n"); 3499 if (segments.length == 1) { 3500 errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo, 3501 error.columnNo + error.tokentext.length(), 3502 ModelBindingManager.getGlobalHash())); 3503 } else { 3504 errorInfo.setEndPosition( 3505 new Pair3<Long, Long, String>(error.lineNo + segments.length - 1, 3506 (long) segments[segments.length - 1].length() + 1, 3507 ModelBindingManager.getGlobalHash())); 3508 } 3509 errorInfo.fillInfo(this); 3510 errorInfos.add(errorInfo); 3511 } 3512 } 3513 } else if (sqlparser.sqlstatements != null) { 3514 for (int i = 0; i < sqlparser.sqlstatements.size(); i++) { 3515 analyzeCustomSqlStmt(sqlparser.sqlstatements.get(i)); 3516 } 3517 } 3518 // getSqlText()!=null means GSP folded the dynamic text. RESOLVED only when the argument 3519 // was a compile-time literal AND it parsed; a variable/expression argument is data-driven 3520 // (often only partially folded, e.g. an unresolved @parameter left in) -> UNRESOLVED. 3521 int[] dynCounts = classifyDynamicSiteLineage(relsBeforeDynamic); 3522 if (!literalArg) { 3523 recordDynamicSqlSite(stmt, dynamicKindOf(executeStmt), 3524 DynamicSqlSite.Status.UNRESOLVED, dynamicReasonOf(executeStmt), dynCounts[0], dynCounts[1]); 3525 } else { 3526 recordDynamicSqlSite(stmt, dynamicKindOf(executeStmt), 3527 result != 0 ? DynamicSqlSite.Status.PARSE_ERROR : DynamicSqlSite.Status.RESOLVED, 3528 result != 0 ? "inner dynamic SQL failed to parse" : null, dynCounts[0], dynCounts[1]); 3529 } 3530 } else if (executeStmt.getModuleName() != null) { 3531 // getSqlText()==null here: a folded literal would have set sqlText. So this is either an 3532 // opaque sp_executesql (data-driven argument), a dynamic proc name (EXEC @var), or an 3533 // ordinary static procedure call. Record the dynamic ones; leave static EXEC proc alone. 3534 if (isSpExecutesql(executeStmt.getModuleName())) { 3535 recordDynamicSqlSite(stmt, DynamicSqlSite.Kind.SP_EXECUTESQL, 3536 DynamicSqlSite.Status.UNRESOLVED, dynamicReasonOf(executeStmt)); 3537 } else if (executeStmt.getModuleName().toString().startsWith("@")) { 3538 recordDynamicSqlSite(stmt, DynamicSqlSite.Kind.OTHER, 3539 DynamicSqlSite.Status.UNRESOLVED, "EXEC target procedure name is a runtime variable"); 3540 } 3541 stmtStack.push(stmt); 3542 analyzeMssqlExecute(executeStmt); 3543 stmtStack.pop(); 3544 } else if (executeStmt.getExecType() == TBaseType.metExecStringCmd) { 3545 // EXEC(<expr>) whose string was not folded: runtime variable / expression, or an inline 3546 // literal the analyzer did not fold (no lineage produced) -> honestly UNRESOLVED. 3547 recordDynamicSqlSite(stmt, DynamicSqlSite.Kind.EXEC_STRING, 3548 DynamicSqlSite.Status.UNRESOLVED, dynamicReasonOf(executeStmt)); 3549 } 3550 } else if (stmt instanceof TExecImmeStmt) { 3551 TExecImmeStmt execImmeStmt = (TExecImmeStmt) stmt; 3552 modelManager.collectDynamicSqlHash(stmt); 3553 synchronized (DataFlowAnalyzer.class) { 3554 TStatementList stmts = execImmeStmt.getDynamicStatements(); 3555 if (stmts != null && stmts.size() > 0) { 3556 for (int i = 0; i < stmts.size(); i++) { 3557 analyzeCustomSqlStmt(stmts.get(i)); 3558 } 3559 } 3560 3561 // Only re-parse the raw dynamic SQL when getDynamicStatements() 3562 // produced nothing. getDynamicStatements() already parses and 3563 // analyzes the fragment with coordinates remapped back to the 3564 // original file position; re-parsing it here with a fresh parser 3565 // would analyze the same SQL a second time and emit duplicate 3566 // hints/lineage carrying fragment-relative (un-remapped) 3567 // coordinates. This fallback still covers the case where 3568 // getDynamicStatements() failed (e.g. dynamic SQL syntax error), 3569 // reporting the parse error below. 3570 String dynamicSql = (stmts == null || stmts.size() == 0) ? execImmeStmt.getDynamicSQL() : null; 3571 if (!SQLUtil.isEmpty(dynamicSql)) { 3572 TGSqlParser sqlparser = new TGSqlParser(option.getVendor()); 3573 sqlparser.sqltext = dynamicSql; 3574 int result = sqlparser.parse(); 3575 // This fresh parse runs the dynamic SQL un-padded, so its 3576 // coordinates are relative to the fragment (first char at 3577 // line 1). Shift them back to the position the fragment 3578 // occupies in the original file, mirroring the shift 3579 // TExecImmeStmt.getDynamicStatements() applies; otherwise 3580 // fallback parse errors for EXECUTE IMMEDIATE text located 3581 // later in the file would report fragment-relative lines. 3582 if (execImmeStmt.getDynamicStringExpr() != null 3583 && execImmeStmt.getDynamicStringExpr().getPlainTextLineNo() != -1) { 3584 int deltaLine = (int) execImmeStmt.getDynamicStringExpr().getPlainTextLineNo() - 1; 3585 int deltaColumn = (int) execImmeStmt.getDynamicStringExpr().getPlainTextColumnNo(); 3586 if ((deltaLine != 0 || deltaColumn != 0) && sqlparser.getSyntaxErrors() != null) { 3587 for (int ei = 0; ei < sqlparser.getSyntaxErrors().size(); ei++) { 3588 TSyntaxError dynErr = sqlparser.getSyntaxErrors().get(ei); 3589 if (dynErr == null) continue; 3590 boolean onFirstLine = (dynErr.lineNo == 1); 3591 dynErr.lineNo += deltaLine; 3592 if (onFirstLine) dynErr.columnNo += deltaColumn; 3593 } 3594 } 3595 } 3596 if (result != 0) { 3597 // a partially resolved value contains placeholder identifiers 3598 // for unknowable parts; a parse failure on such text says 3599 // nothing about the real SQL, so don't report it 3600 errors = execImmeStmt.isDynamicSQLPartial() ? null : sqlparser.getSyntaxErrors(); 3601 if (errors != null && !errors.isEmpty()) { 3602 for (int i = 0; i < errors.size(); i++) { 3603 TSyntaxError error = errors.get(i); 3604 ErrorInfo errorInfo = new ErrorInfo(); 3605 errorInfo.setErrorType(ErrorInfo.SYNTAX_ERROR); 3606 errorInfo.setErrorMessage(getErrorMessage(error, ErrorInfo.SYNTAX_ERROR)); 3607 errorInfo.setStartPosition(new Pair3<Long, Long, String>(error.lineNo, error.columnNo, 3608 ModelBindingManager.getGlobalHash())); 3609 String[] segments = error.tokentext.split("\n"); 3610 if (segments.length == 1) { 3611 errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo, 3612 error.columnNo + error.tokentext.length(), 3613 ModelBindingManager.getGlobalHash())); 3614 } else { 3615 errorInfo.setEndPosition( 3616 new Pair3<Long, Long, String>(error.lineNo + segments.length - 1, 3617 (long) segments[segments.length - 1].length() + 1, 3618 ModelBindingManager.getGlobalHash())); 3619 } 3620 errorInfo.fillInfo(this); 3621 errorInfos.add(errorInfo); 3622 } 3623 } 3624 } else if (sqlparser.sqlstatements != null) { 3625 for (int i = 0; i < sqlparser.sqlstatements.size(); i++) { 3626 analyzeCustomSqlStmt(sqlparser.sqlstatements.get(i)); 3627 } 3628 } 3629 } 3630 } 3631 } else if (stmt instanceof TCallStatement) { 3632 TCallStatement callStmt = (TCallStatement)stmt; 3633 stmtStack.push(stmt); 3634 analyzeCallStmt(callStmt); 3635 stmtStack.pop(); 3636 } else if (stmt instanceof TDb2CallStmt) { 3637 TDb2CallStmt db2CallStmt = (TDb2CallStmt) stmt; 3638 stmtStack.push(stmt); 3639 analyzeDb2CallStmt(db2CallStmt); 3640 stmtStack.pop(); 3641 } else if (stmt instanceof TBasicStmt) { 3642 TBasicStmt oracleBasicStmt = (TBasicStmt) stmt; 3643 stmtStack.push(stmt); 3644 analyzeOracleBasicStmt(oracleBasicStmt); 3645 stmtStack.pop(); 3646 } else if (stmt instanceof TIfStmt) { 3647 TIfStmt ifStmt = (TIfStmt) stmt; 3648 stmtStack.push(stmt); 3649 analyzeIfStmt(ifStmt); 3650 stmtStack.pop(); 3651 } else if (stmt instanceof TElsifStmt) { 3652 TElsifStmt elsIfStmt = (TElsifStmt) stmt; 3653 stmtStack.push(stmt); 3654 analyzeElsIfStmt(elsIfStmt); 3655 stmtStack.pop(); 3656 } else if (stmt.getStatements() != null && stmt.getStatements().size() > 0) { 3657 for (int i = 0; i < stmt.getStatements().size(); i++) { 3658 analyzeCustomSqlStmt(stmt.getStatements().get(i)); 3659 } 3660 } else if (stmt instanceof TCreateIndexSqlStatement) { 3661 stmtStack.push(stmt); 3662 analyzeCreateIndexStageStmt((TCreateIndexSqlStatement) stmt); 3663 stmtStack.pop(); 3664 } else if (stmt instanceof gudusoft.gsqlparser.stmt.mdx.TMdxSelect) { 3665 stmtStack.push(stmt); 3666 analyzeMdxSelectStmt((gudusoft.gsqlparser.stmt.mdx.TMdxSelect) stmt); 3667 stmtStack.pop(); 3668 } else if (stmt instanceof TPowerQueryDocumentStmt) { 3669 stmtStack.push(stmt); 3670 analyzePowerQueryDocumentStmt((TPowerQueryDocumentStmt) stmt); 3671 stmtStack.pop(); 3672 } 3673 } catch (Exception e) { 3674 StringBuffer errorMessage = new StringBuffer(); 3675 errorMessage.append("analyze sql stmt failed, "); 3676 if (stmt.getStartToken() != null) { 3677 errorMessage.append("line: " + stmt.getStartToken().lineNo + ", column: " + stmt.getStartToken().columnNo).append(", "); 3678 } 3679 if (stmt.getGsqlparser() != null && !SQLUtil.isEmpty(stmt.getGsqlparser().sqlfilename)) { 3680 errorMessage.append("file: "+ stmt.getGsqlparser().sqlfilename).append(", "); 3681 } 3682 if (stmt.toString() != null) { 3683 errorMessage.append("sql:\n" + stmt.toString()); 3684 } 3685 logger.error(errorMessage.toString(), e); 3686 ErrorInfo errorInfo = new ErrorInfo(); 3687 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 3688 if (e.getMessage() == null) { 3689 if (e.getStackTrace() != null && e.getStackTrace().length > 0) { 3690 errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getStackTrace()[0].toString()); 3691 } else { 3692 errorInfo.setErrorMessage(e.getClass().getSimpleName()); 3693 } 3694 } else { 3695 errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getMessage()); 3696 } 3697 errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo, 3698 stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash())); 3699 String[] segments = stmt.getEndToken().getAstext().split("\n", -1); 3700 if (segments.length == 1) { 3701 errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo, 3702 stmt.getEndToken().columnNo + stmt.getEndToken().getAstext().length(), 3703 ModelBindingManager.getGlobalHash())); 3704 } else { 3705 errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo + segments.length - 1, 3706 (long) segments[segments.length - 1].length() + 1, ModelBindingManager.getGlobalHash())); 3707 } 3708 errorInfo.fillInfo(this); 3709 errorInfos.add(errorInfo); 3710 } 3711 } 3712 3713 private void analyzePlsqlRecordTypeDefStmt(TPlsqlRecordTypeDefStmt stmt) { 3714 TObjectName typeName = stmt.getTypeName(); 3715 Variable variable = modelFactory.createVariable(typeName); 3716 variable.setSubType(SubType.record_type); 3717 3718 if (stmt.getFieldDeclarations() != null) { 3719 for (int i = 0; i < stmt.getFieldDeclarations().size(); i++) { 3720 TParameterDeclaration param = stmt.getFieldDeclarations().getParameterDeclarationItem(i); 3721 String dataTypeName = param.getDataType().getDataTypeName(); 3722 TObjectName columnName = param.getParameterName(); 3723 TableColumn variableProperty = modelFactory.createTableColumn(variable, columnName, true); 3724 if(dataTypeName.indexOf(".")!=-1) { 3725 String tableName = dataTypeName.substring(0, dataTypeName.lastIndexOf(".")); 3726 Table table = modelFactory.createTableByName(tableName, true); 3727 if(table!=null) { 3728 TableColumn tableColumn = modelFactory.createInsertTableColumn(table, dataTypeName); 3729 if (tableColumn != null) { 3730 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 3731 relation.setEffectType(EffectType.rowtype); 3732 relation.setTarget(new TableColumnRelationshipElement(variableProperty)); 3733 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 3734 } 3735 } 3736 } 3737 } 3738 variable.setDetermined(true); 3739 } 3740 else { 3741 TObjectName starColumn = new TObjectName(); 3742 starColumn.setString("*"); 3743 } 3744 } 3745 3746 private void analyzePlsqlTableTypeDefStmt(TPlsqlTableTypeDefStmt stmt) { 3747 TTypeName typeName = stmt.getElementDataType(); 3748 if (typeName != null && typeName.toString().toUpperCase().indexOf("ROWTYPE") != -1) { 3749 Variable cursorVariable = modelFactory.createVariable(stmt.getTypeName()); 3750 cursorVariable.setSubType(SubType.record_type); 3751 3752 Table variableTable = modelFactory.createTableByName(typeName.getDataTypeName(), false); 3753 if(!variableTable.isCreateTable()) { 3754 TObjectName starColumn1 = new TObjectName(); 3755 starColumn1.setString("*"); 3756 TableColumn variableTableStarColumn = modelFactory.createTableColumn(variableTable, starColumn1, true); 3757 variableTableStarColumn.setShowStar(false); 3758 variableTableStarColumn.setExpandStar(true); 3759 3760 TObjectName starColumn = new TObjectName(); 3761 starColumn.setString("*"); 3762 TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable, starColumn, true); 3763 variableProperty.setShowStar(false); 3764 variableProperty.setExpandStar(true); 3765 3766 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 3767 dataflowRelation.setEffectType(EffectType.rowtype); 3768 dataflowRelation.addSource(new TableColumnRelationshipElement(variableTableStarColumn)); 3769 dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty)); 3770 } else { 3771 for (TableColumn sourceColumn : variableTable.getColumns()) { 3772 String columnName = sourceColumn.getName(); 3773 TObjectName targetColumn = new TObjectName(); 3774 targetColumn.setString(columnName); 3775 TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable, targetColumn, true); 3776 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 3777 dataflowRelation.setEffectType(EffectType.rowtype); 3778 dataflowRelation.addSource(new TableColumnRelationshipElement(sourceColumn)); 3779 dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty)); 3780 } 3781 } 3782 } 3783 } 3784 3785 private void analyzeMssqlCreateType(TMssqlCreateType createType) { 3786 3787 } 3788 3789 private void analyzeMssqlExecute(TMssqlExecute executeStmt) { 3790 if (executeStmt.getModuleName() != null) { 3791 TObjectName module = executeStmt.getModuleName(); 3792 if(module.toString().toLowerCase().endsWith("sp_rename")) { 3793 String oldTableName = SQLUtil.trimColumnStringQuote(executeStmt.getParameters().getExecParameter(0).toString()); 3794 Table oldNameTableModel = modelFactory.createTableByName(oldTableName, true); 3795 List<String> oldTableNames = SQLUtil.parseNames(oldNameTableModel.getName()); 3796 TObjectName oldStarColumn = new TObjectName(); 3797 oldStarColumn.setString("*"); 3798 TableColumn oldTableStarColumn = modelFactory.createTableColumn(oldNameTableModel, oldStarColumn, true); 3799 3800 String newTableName = SQLUtil.trimColumnStringQuote(executeStmt.getParameters().getExecParameter(1).toString()); 3801 List<String> newTableNames = SQLUtil.parseNames(newTableName); 3802 if (oldTableNames.size() > newTableNames.size()) { 3803 for (int i = oldTableNames.size() - newTableNames.size() - 1; i >= 0; i--) { 3804 newTableName = (oldTableNames.get(i) + ".") + newTableName; 3805 } 3806 } 3807 3808 Table newNameTableModel = modelFactory.createTableByName(newTableName, true); 3809 TObjectName newStarColumn = new TObjectName(); 3810 newStarColumn.setString("*"); 3811 TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, newStarColumn, true); 3812 3813 Process process = modelFactory.createProcess(executeStmt); 3814 newNameTableModel.addProcess(process); 3815 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 3816 relation.setEffectType(EffectType.rename_table); 3817 relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn)); 3818 relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn)); 3819 relation.setProcess(process); 3820 3821 if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) { 3822 oldTableStarColumn.setShowStar(false); 3823 relation.setShowStarRelation(false); 3824 } 3825 3826 if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) { 3827 newTableStarColumn.setShowStar(false); 3828 relation.setShowStarRelation(false); 3829 } 3830 } 3831 else if(module.toString().toLowerCase().endsWith("sp_executesql")) { 3832 String sql = SQLUtil.trimColumnStringQuote(executeStmt.getParameters().getExecParameter(0).toString()); 3833 if(sql.startsWith("N")) { 3834 sql = SQLUtil.trimColumnStringQuote(sql.substring(1)); 3835 } 3836 executeDynamicSql(sql); 3837 } 3838 else { 3839 int argumentSize = executeStmt.getParameters() == null ? 0 : executeStmt.getParameters().size(); 3840 String procedureNameWithArgSize = module.toString() + "(" + argumentSize + ")"; 3841 if (argumentSize <= 0 || !DlineageUtil.supportFunctionOverride(option.getVendor())) { 3842 procedureNameWithArgSize = module.toString(); 3843 } 3844 if (procedureDDLMap.containsKey(procedureNameWithArgSize)) { 3845 analyzeCustomSqlStmt(procedureDDLMap.get(procedureNameWithArgSize)); 3846 } 3847 Procedure procedure = modelFactory.createProcedureByName(module, executeStmt.getParameters() == null ? 0 : executeStmt.getParameters().size()); 3848 String procedureParent = getProcedureParentName(executeStmt); 3849 if (procedureParent != null) { 3850 Procedure caller = modelManager 3851 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 3852 if (caller != null) { 3853 CallRelationship callRelation = modelFactory.createCallRelation(); 3854 callRelation.setCallObject(executeStmt); 3855 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 3856 callRelation.addSource(new ProcedureRelationshipElement(procedure)); 3857 if(isBuiltInFunctionName(module) || isKeyword(module)){ 3858 callRelation.setBuiltIn(true); 3859 } 3860 } 3861 } 3862 3863 if (procedure.getArguments() != null) { 3864 for (int i = 0; i < procedure.getArguments().size(); i++) { 3865 Argument argument = procedure.getArguments().get(i); 3866 Variable variable = modelFactory.createVariable(procedure, argument.getName(), false); 3867 if (variable != null) { 3868 if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) { 3869 Transform transform = new Transform(); 3870 transform.setType(Transform.FUNCTION); 3871 transform.setCode(module); 3872 variable.getColumns().get(0).setTransform(transform); 3873 } 3874 Process process = modelFactory.createProcess(executeStmt); 3875 variable.addProcess(process); 3876 analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), executeStmt, argument.getName(), i, process); 3877 } 3878 } 3879 } 3880 } 3881 } 3882 } 3883 3884 private void analyzeDropTableStmt(TDropTableSqlStatement stmt) { 3885 TTable dropTable = stmt.getTargetTable(); 3886 if(dropTable == null) { 3887 return; 3888 } 3889 Table tableModel = modelManager.getTableByName(DlineageUtil.getTableFullName(dropTable.getTableName().toString())); 3890 if(tableModel!=null) { 3891 modelManager.dropTable(tableModel); 3892 } 3893 3894 if(option.getAnalyzeMode() == AnalyzeMode.crud) { 3895 tableModel = modelFactory.createTable(dropTable); 3896 CrudRelationship crudRelationship = modelFactory.createCrudRelation(); 3897 crudRelationship.setTarget(new TableRelationshipElement(tableModel)); 3898 crudRelationship.setEffectType(EffectType.drop_table); 3899 } 3900 } 3901 3902 private void analyzeTruncateTableStmt(TTruncateStatement stmt) { 3903 if(option.getAnalyzeMode() == AnalyzeMode.crud) { 3904 TObjectName table = stmt.getTableName(); 3905 Table tableModel = modelFactory.createTableByName(table); 3906 CrudRelationship crudRelationship = modelFactory.createCrudRelation(); 3907 crudRelationship.setTarget(new TableRelationshipElement(tableModel)); 3908 crudRelationship.setEffectType(EffectType.truncate_table); 3909 } 3910 } 3911 3912 private void analyzeCallStmt(TCallStatement callStmt) { 3913 if (callStmt.getRoutineExpr() != null && callStmt.getRoutineExpr().getFunctionCall() != null) { 3914 3915 TFunctionCall functionCall = callStmt.getRoutineExpr().getFunctionCall(); 3916 Procedure callee = modelManager.getProcedureByName( 3917 DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 3918 if (callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) { 3919 analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 3920 callee = modelManager.getProcedureByName(DlineageUtil 3921 .getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 3922 } 3923 if (callee != null) { 3924 String procedureParent = getProcedureParentName(callStmt); 3925 if (procedureParent != null) { 3926 Procedure caller = modelManager 3927 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 3928 if (caller != null) { 3929 CallRelationship callRelation = modelFactory.createCallRelation(); 3930 callRelation.setCallObject(callStmt); 3931 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 3932 callRelation.addSource(new ProcedureRelationshipElement(callee)); 3933 if (isBuiltInFunctionName(functionCall.getFunctionName()) 3934 || isKeyword(functionCall.getFunctionName())) { 3935 callRelation.setBuiltIn(true); 3936 } 3937 } 3938 } 3939 if (callee.getArguments() != null) { 3940 for (int i = 0; i < callee.getArguments().size(); i++) { 3941 Argument argument = callee.getArguments().get(i); 3942 Variable variable = modelFactory.createVariable(callee, argument.getName(), false); 3943 if (variable != null) { 3944 if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) { 3945 Transform transform = new Transform(); 3946 transform.setType(Transform.FUNCTION); 3947 transform.setCode(functionCall); 3948 variable.getColumns().get(0).setTransform(transform); 3949 } 3950 Process process = modelFactory.createProcess(callStmt); 3951 variable.addProcess(process); 3952 analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, i, 3953 process); 3954 } 3955 } 3956 } 3957 } else { 3958 Function function = (Function) createFunction(functionCall); 3959 String procedureParent = getProcedureParentName(callStmt); 3960 if (procedureParent != null) { 3961 Procedure caller = modelManager 3962 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 3963 if (caller != null) { 3964 CallRelationship callRelation = modelFactory.createCallRelation(); 3965 callRelation.setCallObject(callStmt); 3966 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 3967 callRelation.addSource(new FunctionRelationshipElement(function)); 3968 if (isBuiltInFunctionName(functionCall.getFunctionName()) 3969 || isKeyword(functionCall.getFunctionName())) { 3970 callRelation.setBuiltIn(true); 3971 } 3972 } 3973 } 3974 } 3975 } 3976 else if (callStmt.getRoutineName() != null) { 3977 TObjectName function = callStmt.getRoutineName(); 3978 String functionName = function.toString(); 3979 Procedure callee = modelManager.getProcedureByName( 3980 DlineageUtil.getIdentifierNormalTableName(functionName)); 3981 if (callee == null && procedureDDLMap.containsKey(functionName)) { 3982 analyzeCustomSqlStmt(procedureDDLMap.get(functionName)); 3983 callee = modelManager.getProcedureByName(functionName); 3984 } 3985 if (callee != null) { 3986 String procedureParent = getProcedureParentName(callStmt); 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(callStmt); 3993 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 3994 callRelation.addSource(new ProcedureRelationshipElement(callee)); 3995 if (isBuiltInFunctionName(function) 3996 || isKeyword(function)) { 3997 callRelation.setBuiltIn(true); 3998 } 3999 } 4000 } 4001 if (callee.getArguments() != null) { 4002 for (int i = 0; i < callee.getArguments().size(); i++) { 4003 Argument argument = callee.getArguments().get(i); 4004 Variable variable = modelFactory.createVariable(callee, argument.getName(), false); 4005 if (variable != null) { 4006 if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) { 4007 Transform transform = new Transform(); 4008 transform.setType(Transform.FUNCTION); 4009 transform.setCode(callStmt); 4010 variable.getColumns().get(0).setTransform(transform); 4011 } 4012 Process process = modelFactory.createProcess(callStmt); 4013 variable.addProcess(process); 4014 analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), callStmt, i, 4015 process); 4016 } 4017 } 4018 } 4019 } 4020 } 4021 } 4022 4023 /** 4024 * DB2's CALL node is {@link TDb2CallStmt} (a sibling of {@link TCallStatement}, 4025 * not a subclass), so the generic call dispatch never reaches it. Resolve its 4026 * caller/callee and emit the call relationship exactly as the 4027 * {@link #analyzeCallStmt} getRoutineName path does, using the DB2 accessors 4028 * getProcedureName()/getParameters(). 4029 */ 4030 private void analyzeDb2CallStmt(TDb2CallStmt callStmt) { 4031 if (callStmt.getProcedureName() == null) { 4032 return; 4033 } 4034 TObjectName function = callStmt.getProcedureName(); 4035 String functionName = function.toString(); 4036 // DB2 supports procedure overloading by arity, so overloadable procedures 4037 // register under a "name(argCount)" key (see getFunctionNameWithArgNum). 4038 // Resolve by name+argCount first to bind the correct overload, then fall 4039 // back to the plain name for the single-definition / non-overloaded case. 4040 String nameWithArgNum = functionName; 4041 if (callStmt.getParameters() != null 4042 && DlineageUtil.supportFunctionOverride(ModelBindingManager.getGlobalVendor())) { 4043 nameWithArgNum = functionName + "(" + callStmt.getParameters().size() + ")"; 4044 } 4045 Procedure callee = modelManager.getProcedureByName( 4046 DlineageUtil.getIdentifierNormalTableName(nameWithArgNum)); 4047 if (callee == null && !nameWithArgNum.equals(functionName)) { 4048 callee = modelManager.getProcedureByName( 4049 DlineageUtil.getIdentifierNormalTableName(functionName)); 4050 } 4051 if (callee == null && procedureDDLMap.containsKey(nameWithArgNum)) { 4052 analyzeCustomSqlStmt(procedureDDLMap.get(nameWithArgNum)); 4053 callee = modelManager.getProcedureByName(nameWithArgNum); 4054 } 4055 if (callee == null && procedureDDLMap.containsKey(functionName)) { 4056 analyzeCustomSqlStmt(procedureDDLMap.get(functionName)); 4057 callee = modelManager.getProcedureByName(functionName); 4058 } 4059 if (callee != null) { 4060 String procedureParent = getProcedureParentName(callStmt); 4061 if (procedureParent != null) { 4062 Procedure caller = modelManager 4063 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 4064 if (caller != null) { 4065 CallRelationship callRelation = modelFactory.createCallRelation(); 4066 callRelation.setCallObject(callStmt); 4067 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 4068 callRelation.addSource(new ProcedureRelationshipElement(callee)); 4069 if (isBuiltInFunctionName(function) || isKeyword(function)) { 4070 callRelation.setBuiltIn(true); 4071 } 4072 } 4073 } 4074 if (callee.getArguments() != null) { 4075 for (int i = 0; i < callee.getArguments().size(); i++) { 4076 Argument argument = callee.getArguments().get(i); 4077 Variable variable = modelFactory.createVariable(callee, argument.getName(), false); 4078 if (variable != null) { 4079 if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) { 4080 Transform transform = new Transform(); 4081 transform.setType(Transform.FUNCTION); 4082 transform.setCode(callStmt); 4083 variable.getColumns().get(0).setTransform(transform); 4084 } 4085 Process process = modelFactory.createProcess(callStmt); 4086 variable.addProcess(process); 4087 analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), callStmt, i, 4088 process); 4089 } 4090 } 4091 } 4092 } 4093 } 4094 4095 private boolean analyzeCustomFunctionCall(TFunctionCall functionCall) { 4096 Procedure callee = modelManager.getProcedureByName( 4097 DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 4098 if(callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) { 4099 analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 4100 callee = modelManager.getProcedureByName( 4101 DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 4102 } 4103 if (callee != null) { 4104 String procedureParent = getProcedureParentName(stmtStack.peek()); 4105 if (procedureParent != null) { 4106 Procedure caller = modelManager 4107 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 4108 if (caller != null) { 4109 CallRelationship callRelation = modelFactory.createCallRelation(); 4110 callRelation.setCallObject(functionCall); 4111 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 4112 callRelation.addSource(new ProcedureRelationshipElement(callee)); 4113 if(isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName())){ 4114 callRelation.setBuiltIn(true); 4115 } 4116 } 4117 } 4118 if (callee.getArguments() != null) { 4119 for (int i = 0; i < callee.getArguments().size(); i++) { 4120 Argument argument = callee.getArguments().get(i); 4121 Variable variable = modelFactory.createVariable(callee, argument.getName(), false); 4122 if(variable!=null) { 4123 if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) { 4124 Transform transform = new Transform(); 4125 transform.setType(Transform.FUNCTION); 4126 transform.setCode(functionCall); 4127 variable.getColumns().get(0).setTransform(transform); 4128 } 4129 Process process = modelFactory.createProcess(functionCall); 4130 variable.addProcess(process); 4131 analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, i, process); 4132 } 4133 } 4134 } 4135 return true; 4136 } 4137 return false; 4138 } 4139 4140 private void analyzeOracleBasicStmt(TBasicStmt oracleBasicStmt) { 4141 if (oracleBasicStmt.getExpr() == null || oracleBasicStmt.getExpr().getFunctionCall() == null) { 4142 return; 4143 } 4144 4145 TFunctionCall functionCall = oracleBasicStmt.getExpr().getFunctionCall(); 4146 Procedure callee = modelManager.getProcedureByName( 4147 DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 4148 if(callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) { 4149 analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 4150 callee = modelManager.getProcedureByName( 4151 DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 4152 } 4153 if (callee != null) { 4154 String procedureParent = getProcedureParentName(oracleBasicStmt); 4155 if (procedureParent != null) { 4156 Procedure caller = modelManager 4157 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 4158 if (caller != null) { 4159 CallRelationship callRelation = modelFactory.createCallRelation(); 4160 callRelation.setCallObject(functionCall); 4161 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 4162 callRelation.addSource(new ProcedureRelationshipElement(callee)); 4163 if (functionChecker.isOraclePredefinedPackageFunction(functionCall.getFunctionName().toString()) 4164 || (isBuiltInFunctionName(functionCall.getFunctionName()) 4165 || isKeyword(functionCall.getFunctionName()))) { 4166 callRelation.setBuiltIn(true); 4167 } 4168 } 4169 } 4170 if (callee.getArguments() != null) { 4171 for (int i = 0; i < callee.getArguments().size(); i++) { 4172 Argument argument = callee.getArguments().get(i); 4173 Variable variable = modelFactory.createVariable(callee, argument.getName(), false); 4174 if(variable!=null) { 4175 if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) { 4176 Transform transform = new Transform(); 4177 transform.setType(Transform.FUNCTION); 4178 transform.setCode(functionCall); 4179 variable.getColumns().get(0).setTransform(transform); 4180 } 4181 Process process = modelFactory.createProcess(functionCall); 4182 variable.addProcess(process); 4183 analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, i, process); 4184 } 4185 } 4186 } 4187 } else { 4188 Function function = modelFactory.createFunction(functionCall); 4189 String procedureParent = getProcedureParentName(oracleBasicStmt); 4190 if (procedureParent != null) { 4191 Procedure caller = modelManager 4192 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 4193 if (caller != null) { 4194 CallRelationship callRelation = modelFactory.createCallRelation(); 4195 callRelation.setCallObject(functionCall); 4196 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 4197 callRelation.addSource(new FunctionRelationshipElement(function)); 4198 if (functionChecker.isOraclePredefinedPackageFunction(functionCall.getFunctionName().toString()) 4199 || (isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName()))) { 4200 callRelation.setBuiltIn(true); 4201 } 4202 } 4203 } 4204 } 4205 } 4206 4207 private void analyzeIfStmt(TIfStmt ifStmt) { 4208 if (ifStmt.getCondition() != null) { 4209 columnsInExpr visitor = new columnsInExpr(); 4210 ifStmt.getCondition().inOrderTraverse(visitor); 4211 List<TParseTreeNode> functions = visitor.getFunctions(); 4212 4213 if (functions != null && !functions.isEmpty()) { 4214 for (int i = 0; i < functions.size(); i++) { 4215 if (!(functions.get(i) instanceof TFunctionCall)) 4216 continue; 4217 TFunctionCall functionCall = (TFunctionCall) functions.get(i); 4218 Procedure callee = modelManager.getProcedureByName(DlineageUtil 4219 .getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 4220 if(callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) { 4221 analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 4222 callee = modelManager.getProcedureByName( 4223 DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 4224 } 4225 if (callee != null) { 4226 String procedureParent = getProcedureParentName(ifStmt); 4227 if (procedureParent != null) { 4228 Procedure caller = modelManager 4229 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 4230 if (caller != null) { 4231 CallRelationship callRelation = modelFactory.createCallRelation(); 4232 callRelation.setCallObject(functionCall); 4233 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 4234 callRelation.addSource(new ProcedureRelationshipElement(callee)); 4235 if (isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName())) { 4236 callRelation.setBuiltIn(true); 4237 } 4238 } 4239 } 4240 if (callee.getArguments() != null) { 4241 for (int j = 0; j < callee.getArguments().size(); j++) { 4242 Argument argument = callee.getArguments().get(j); 4243 Variable variable = modelFactory.createVariable(callee, argument.getName(), false); 4244 if(variable!=null) { 4245 if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) { 4246 Transform transform = new Transform(); 4247 transform.setType(Transform.FUNCTION); 4248 transform.setCode(functionCall); 4249 variable.getColumns().get(0).setTransform(transform); 4250 } 4251 Process process = modelFactory.createProcess(functionCall); 4252 variable.addProcess(process); 4253 analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, j, process); 4254 } 4255 } 4256 } 4257 } else { 4258 Function function = modelFactory.createFunction(functionCall); 4259 String procedureParent = getProcedureParentName(ifStmt); 4260 if (procedureParent != null) { 4261 Procedure caller = modelManager 4262 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 4263 if (caller != null) { 4264 CallRelationship callRelation = modelFactory.createCallRelation(); 4265 callRelation.setCallObject(functionCall); 4266 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 4267 callRelation.addSource(new FunctionRelationshipElement(function)); 4268 if (isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName())) { 4269 callRelation.setBuiltIn(true); 4270 } 4271 } 4272 } 4273 } 4274 } 4275 } 4276 } 4277 4278 if (ifStmt.getThenStatements() != null) { 4279 for (int i = 0; i < ifStmt.getThenStatements().size(); ++i) { 4280 analyzeCustomSqlStmt(ifStmt.getThenStatements().get(i)); 4281 ResultSet returnResult = modelFactory.createResultSet(ifStmt.getThenStatements().get(i), false); 4282 if(returnResult!=null){ 4283 for(ResultColumn resultColumn: returnResult.getColumns()){ 4284 analyzeFilterCondition(resultColumn, ifStmt.getCondition(), null, null, EffectType.function); 4285 } 4286 } 4287 } 4288 } 4289 4290 if (ifStmt.getElseifStatements() != null) { 4291 for (int i = 0; i < ifStmt.getElseifStatements().size(); ++i) { 4292 analyzeCustomSqlStmt(ifStmt.getElseifStatements().get(i)); 4293 } 4294 } 4295 4296 if (ifStmt.getElseStatements() != null) { 4297 for (int i = 0; i < ifStmt.getElseStatements().size(); ++i) { 4298 analyzeCustomSqlStmt(ifStmt.getElseStatements().get(i)); 4299 } 4300 } 4301 } 4302 4303 private void analyzeElsIfStmt(TElsifStmt elsIfStmt) { 4304 if (elsIfStmt.getCondition() != null) { 4305 columnsInExpr visitor = new columnsInExpr(); 4306 elsIfStmt.getCondition().inOrderTraverse(visitor); 4307 List<TParseTreeNode> functions = visitor.getFunctions(); 4308 4309 if (functions != null && !functions.isEmpty()) { 4310 for (int i = 0; i < functions.size(); i++) { 4311 if (!(functions.get(i) instanceof TFunctionCall)) 4312 continue; 4313 TFunctionCall functionCall = (TFunctionCall) functions.get(i); 4314 Procedure callee = modelManager.getProcedureByName(DlineageUtil 4315 .getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 4316 if(callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) { 4317 analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 4318 callee = modelManager.getProcedureByName( 4319 DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 4320 } 4321 if (callee != null) { 4322 String procedureParent = getProcedureParentName(elsIfStmt); 4323 if (procedureParent != null) { 4324 Procedure caller = modelManager 4325 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 4326 if (caller != null) { 4327 CallRelationship callRelation = modelFactory.createCallRelation(); 4328 callRelation.setCallObject(functionCall); 4329 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 4330 callRelation.addSource(new ProcedureRelationshipElement(callee)); 4331 if(isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName())){ 4332 callRelation.setBuiltIn(true); 4333 } 4334 } 4335 } 4336 if (callee.getArguments() != null) { 4337 for (int j = 0; j < callee.getArguments().size(); j++) { 4338 Argument argument = callee.getArguments().get(j); 4339 Variable variable = modelFactory.createVariable(callee, argument.getName(), false); 4340 if(variable!=null) { 4341 if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) { 4342 Transform transform = new Transform(); 4343 transform.setType(Transform.FUNCTION); 4344 transform.setCode(functionCall); 4345 variable.getColumns().get(0).setTransform(transform); 4346 } 4347 Process process = modelFactory.createProcess(functionCall); 4348 variable.addProcess(process); 4349 analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, j, process); 4350 } 4351 } 4352 } 4353 } else { 4354 Function function = modelFactory.createFunction(functionCall); 4355 String procedureParent = getProcedureParentName(elsIfStmt); 4356 if (procedureParent != null) { 4357 Procedure caller = modelManager 4358 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 4359 if (caller != null) { 4360 CallRelationship callRelation = modelFactory.createCallRelation(); 4361 callRelation.setCallObject(functionCall); 4362 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 4363 callRelation.addSource(new FunctionRelationshipElement(function)); 4364 if(isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName())){ 4365 callRelation.setBuiltIn(true); 4366 } 4367 } 4368 } 4369 } 4370 } 4371 } 4372 } 4373 4374 if (elsIfStmt.getThenStatements() != null) { 4375 for (int i = 0; i < elsIfStmt.getThenStatements().size(); ++i) { 4376 ResultSet returnResult = modelFactory.createResultSet(elsIfStmt.getThenStatements().get(i), false); 4377 if (returnResult != null) { 4378 for (ResultColumn resultColumn : returnResult.getColumns()) { 4379 analyzeFilterCondition(resultColumn, elsIfStmt.getCondition(), null, null, EffectType.function); 4380 } 4381 } 4382 analyzeCustomSqlStmt(elsIfStmt.getThenStatements().get(i)); 4383 } 4384 } 4385 } 4386 4387 private void analyzeCloneTableStmt(TCreateTableSqlStatement stmt) { 4388 if (stmt.getCloneSourceTable() != null) { 4389 Table sourceTable = modelFactory.createTableByName(stmt.getCloneSourceTable()); 4390 Table cloneTable = modelFactory.createTableByName(stmt.getTableName()); 4391 // Clone creates the target. Parse fact, set regardless of source 4392 // resolution (the gated setFromDDL below stays as-is). See 4393 // dlineage-authoritative-endpoint-classification.md. 4394 cloneTable.setCreatedInSql(true); 4395 cloneTable.setEndpointIntroduction(EndpointIntroduction.CLONE_TABLE); 4396 Process process = modelFactory.createProcess(stmt); 4397 cloneTable.addProcess(process); 4398 4399 if (sourceTable.isDetermined()) { 4400 for (int k = 0; k < sourceTable.getColumns().size(); k++) { 4401 TableColumn sourceColumn = sourceTable.getColumns().get(k); 4402 TObjectName objectName = new TObjectName(); 4403 objectName.setString(sourceColumn.getName()); 4404 TableColumn tableColumn = modelFactory.createTableColumn(cloneTable, objectName, true); 4405 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 4406 dataflowRelation.setEffectType(EffectType.clone_table); 4407 dataflowRelation 4408 .addSource(new TableColumnRelationshipElement(sourceColumn)); 4409 dataflowRelation.setTarget(new TableColumnRelationshipElement(tableColumn)); 4410 dataflowRelation.setProcess(process); 4411 } 4412 cloneTable.setDetermined(true); 4413 cloneTable.setFromDDL(true); 4414 } else { 4415 TObjectName sourceName = new TObjectName(); 4416 sourceName.setString("*"); 4417 TableColumn sourceTableColumn = modelFactory.createTableColumn(sourceTable, sourceName, false); 4418 TObjectName targetName = new TObjectName(); 4419 targetName.setString("*"); 4420 TableColumn targetTableColumn = modelFactory.createTableColumn(cloneTable, targetName, false); 4421 if(sourceTableColumn!=null && targetTableColumn!=null) { 4422 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 4423 dataflowRelation.setEffectType(EffectType.clone_table); 4424 dataflowRelation 4425 .addSource(new TableColumnRelationshipElement(sourceTableColumn)); 4426 dataflowRelation.setTarget(new TableColumnRelationshipElement(targetTableColumn)); 4427 dataflowRelation.setProcess(process); 4428 } 4429 } 4430 } 4431 } 4432 4433 private void analyzeCloneDatabaseStmt(TCreateDatabaseSqlStatement stmt) { 4434 if (stmt.getCloneSourceDb() != null) { 4435 Database sourceDatabase = modelFactory.createDatabase(stmt.getCloneSourceDb()); 4436 Database cloneDatabase = modelFactory.createDatabase(stmt.getDatabaseName()); 4437 Process process = modelFactory.createProcess(stmt); 4438 cloneDatabase.addProcess(process); 4439 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 4440 relation.setEffectType(EffectType.clone_database); 4441 relation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(cloneDatabase.getRelationRows())); 4442 relation.addSource( 4443 new RelationRowsRelationshipElement<TableRelationRows>(sourceDatabase.getRelationRows())); 4444 relation.setProcess(process); 4445 } 4446 } 4447 4448 private void analyzeCloneSchemaStmt(TCreateSchemaSqlStatement stmt) { 4449 if (stmt.getCloneSourceSchema() != null) { 4450 Schema sourceSchema = modelFactory.createSchema(stmt.getCloneSourceSchema()); 4451 Schema cloneSchema = modelFactory.createSchema(stmt.getSchemaName()); 4452 Process process = modelFactory.createProcess(stmt); 4453 cloneSchema.addProcess(process); 4454 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 4455 relation.setEffectType(EffectType.clone_schema); 4456 relation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(cloneSchema.getRelationRows())); 4457 relation.addSource(new RelationRowsRelationshipElement<TableRelationRows>(sourceSchema.getRelationRows())); 4458 relation.setProcess(process); 4459 } 4460 } 4461 4462 /** 4463 * Record one dynamic-SQL site. Span is the statement extent (1-based, end-exclusive), tagged with 4464 * the per-statement file hash, mirroring the {@link ErrorInfo} position convention. When the 4465 * {@code reportDynamicSqlSitesAsErrors} option is on, non-RESOLVED sites are also mirrored into an 4466 * {@link ErrorInfo} so legacy {@code getErrorMessages()} consumers can see them. 4467 */ 4468 private void recordDynamicSqlSite(TCustomSqlStatement stmt, DynamicSqlSite.Kind kind, 4469 DynamicSqlSite.Status status, String reason) { 4470 recordDynamicSqlSite(stmt, kind, status, reason, 0, 0); 4471 } 4472 4473 private void recordDynamicSqlSite(TCustomSqlStatement stmt, DynamicSqlSite.Kind kind, 4474 DynamicSqlSite.Status status, String reason, int resolvedCount, int partialCount) { 4475 if (stmt == null || stmt.getStartToken() == null || stmt.getEndToken() == null) { 4476 return; 4477 } 4478 Pair3<Long, Long, String> start = new Pair3<Long, Long, String>(stmt.getStartToken().lineNo, 4479 stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash()); 4480 Pair3<Long, Long, String> end; 4481 String[] segments = stmt.getEndToken().getAstext().split("\n", -1); 4482 if (segments.length == 1) { 4483 end = new Pair3<Long, Long, String>(stmt.getEndToken().lineNo, 4484 stmt.getEndToken().columnNo + stmt.getEndToken().getAstext().length(), 4485 ModelBindingManager.getGlobalHash()); 4486 } else { 4487 end = new Pair3<Long, Long, String>(stmt.getEndToken().lineNo + segments.length - 1, 4488 (long) segments[segments.length - 1].length() + 1, ModelBindingManager.getGlobalHash()); 4489 } 4490 dynamicSqlSites.add(new DynamicSqlSite(kind, status, reason, start, end, resolvedCount, partialCount)); 4491 4492 if (status != DynamicSqlSite.Status.RESOLVED && option != null 4493 && option.isReportDynamicSqlSitesAsErrors()) { 4494 ErrorInfo errorInfo = new ErrorInfo(); 4495 errorInfo.setErrorType(ErrorInfo.DYNAMIC_SQL_UNRESOLVED); 4496 errorInfo.setErrorMessage(reason != null ? reason : "dynamic SQL not resolved"); 4497 errorInfo.setStartPosition(start); 4498 errorInfo.setEndPosition(end); 4499 errorInfo.fillInfo(this); 4500 errorInfos.add(errorInfo); 4501 } 4502 } 4503 4504 /** 4505 * Classify the lineage edges a folded dynamic site produced. {@code relsBefore} is the relation 4506 * snapshot taken immediately before the folded SQL was analyzed; the tail of the current relation set 4507 * is this site's delta (relationHolder is insertion-ordered). counts[0]=resolved (edge into a real 4508 * target column), counts[1]=partial (edge into a T-SQL variable / placeholder target). Edges whose 4509 * target is an intermediate result-set are ignored — only final-target edges are counted. 4510 */ 4511 private int[] classifyDynamicSiteLineage(int beforeCount) { 4512 int resolved = 0; 4513 int partial = 0; 4514 Relationship[] after = modelManager.getRelations(); 4515 for (int i = beforeCount; i < after.length; i++) { 4516 Relationship r = after[i]; 4517 if (r == null || !(r.getTarget() instanceof TableColumnRelationshipElement)) { 4518 continue; 4519 } 4520 TableColumn targetColumn = ((TableColumnRelationshipElement) r.getTarget()).getElement(); 4521 Table targetTable = targetColumn == null ? null : targetColumn.getTable(); 4522 if (isUnresolvedTargetTable(targetTable)) { 4523 partial++; 4524 } else { 4525 resolved++; 4526 } 4527 } 4528 return new int[] { resolved, partial }; 4529 } 4530 4531 /** 4532 * A folded dynamic site's target is "unresolved" when it is a T-SQL variable / placeholder rather 4533 * than a real object. When GSP only partially folds (e.g. {@code EXEC sp_executesql @sql} → 4534 * {@code INSERT INTO @p SELECT ...}), the re-parsed target is a table literally named {@code @p}; 4535 * its {@code isVariable()} flag is not set, so the reliable signal is a name starting with '@'. 4536 */ 4537 private boolean isUnresolvedTargetTable(Table table) { 4538 if (table == null) { 4539 return true; 4540 } 4541 if (table.isVariable() || table.isPseudo()) { 4542 return true; 4543 } 4544 String name = table.getName(); 4545 if (name != null) { 4546 name = name.replace("[", "").replace("]", "").replace("\"", "").trim(); 4547 if (name.startsWith("@")) { 4548 return true; 4549 } 4550 } 4551 return false; 4552 } 4553 4554 /** True when a module name resolves to sp_executesql, ignoring schema qualifier and brackets/quotes. */ 4555 private boolean isSpExecutesql(TObjectName moduleName) { 4556 if (moduleName == null) { 4557 return false; 4558 } 4559 String s = moduleName.toString(); 4560 int dot = s.lastIndexOf('.'); 4561 if (dot >= 0) { 4562 s = s.substring(dot + 1); 4563 } 4564 s = s.replace("[", "").replace("]", "").replace("\"", "").replace("`", "").trim(); 4565 return "sp_executesql".equalsIgnoreCase(s); 4566 } 4567 4568 /** Kind of a {@link TMssqlExecute} dynamic site: sp_executesql vs the EXEC(string) family. */ 4569 private DynamicSqlSite.Kind dynamicKindOf(TMssqlExecute e) { 4570 if (e.getExecType() == TBaseType.metExecStringCmd) { 4571 return DynamicSqlSite.Kind.EXEC_STRING; 4572 } 4573 if (isSpExecutesql(e.getModuleName())) { 4574 return DynamicSqlSite.Kind.SP_EXECUTESQL; 4575 } 4576 return DynamicSqlSite.Kind.OTHER; 4577 } 4578 4579 /** The dynamic-SQL argument expression of a {@link TMssqlExecute}, or null. */ 4580 private TExpression dynamicArgOf(TMssqlExecute e) { 4581 if (e.getExecType() == TBaseType.metExecStringCmd) { 4582 if (e.getStringValues() != null && e.getStringValues().size() > 0) { 4583 return e.getStringValues().getExpression(0); 4584 } 4585 return null; 4586 } 4587 if (e.getParameters() != null && e.getParameters().size() > 0) { 4588 TExecParameter p = e.getParameters().getExecParameter(0); 4589 if (p != null) { 4590 return p.getParameterValue(); 4591 } 4592 } 4593 return null; 4594 } 4595 4596 /** 4597 * True only when the dynamic-SQL argument is a compile-time string literal. A variable or 4598 * expression argument is data-driven: even when GSP partially folds it (e.g. {@code @sql} → 4599 * {@code INSERT INTO @t SELECT ...} with an unresolved parameter left in), the site is NOT 4600 * fully resolved, so it must not be reported RESOLVED. 4601 */ 4602 private boolean isLiteralDynamicArg(TMssqlExecute e) { 4603 TExpression arg = dynamicArgOf(e); 4604 return arg != null && arg.getExpressionType() == EExpressionType.simple_constant_t; 4605 } 4606 4607 /** Refine the UNRESOLVED reason by inspecting the dynamic argument expression. */ 4608 private String dynamicReasonOf(TMssqlExecute e) { 4609 TExpression arg = dynamicArgOf(e); 4610 if (arg == null) { 4611 return "dynamic SQL target could not be resolved"; 4612 } 4613 if (arg.getExpressionType() == EExpressionType.simple_object_name_t && arg.getObjectOperand() != null 4614 && arg.getObjectOperand().getDbObjectType() == EDbObjectType.variable) { 4615 return "argument is a runtime variable"; 4616 } 4617 if (arg.getExpressionType() == EExpressionType.simple_constant_t) { 4618 return "inline literal not folded; no lineage produced"; 4619 } 4620 return "argument is a runtime expression or partially-folded variable"; 4621 } 4622 4623 private void executeDynamicSql(String sql) { 4624 TGSqlParser sqlparser = new TGSqlParser(option.getVendor()); 4625 sqlparser.sqltext = sql; 4626 int result = sqlparser.parse(); 4627 if (result == 0) { 4628 for (int i = 0; i < sqlparser.sqlstatements.size(); i++) { 4629 analyzeCustomSqlStmt(sqlparser.sqlstatements.get(i)); 4630 } 4631 } 4632 } 4633 4634 private void extractSnowflakeSQLFromProcedure(TCreateProcedureStmt procedure) { 4635 Map<String, String> argMap = new LinkedHashMap<String, String>(); 4636 if (procedure.getParameterDeclarations() != null) { 4637 for (int i = 0; i < procedure.getParameterDeclarations().size(); i++) { 4638 TParameterDeclaration def = procedure.getParameterDeclarations().getParameterDeclarationItem(i); 4639 argMap.put(def.getParameterName().toString(), def.getDataType().getDataTypeName()); 4640 } 4641 } 4642 StringBuilder buffer = new StringBuilder(); 4643 buffer.append("(function("); 4644 String[] args = argMap.keySet().toArray(new String[0]); 4645 for (int i = 0; i < args.length; i++) { 4646 buffer.append(args[i].toUpperCase()); 4647 if (i < args.length - 1) { 4648 buffer.append(","); 4649 } 4650 } 4651 buffer.append("){\n"); 4652 4653 int start = -1; 4654 int end = -1; 4655 boolean dollar = false; 4656 boolean quote = false; 4657 if (procedure.getRoutineBody().indexOf("$$") != -1) { 4658 start = procedure.getRoutineBody().indexOf("$$") + 2; 4659 end = procedure.getRoutineBody().lastIndexOf("$$") - 1; 4660 dollar = true; 4661 } else if (procedure.getRoutineBody().indexOf("'") != -1) { 4662 start = procedure.getRoutineBody().indexOf("'") + 1; 4663 end = procedure.getRoutineBody().lastIndexOf("'"); 4664 quote = true; 4665 } 4666 String body = procedure.getRoutineBody().substring(start, end); 4667 if (dollar && body.indexOf("`") != -1) { 4668 Pattern pattern = Pattern.compile("`.+?`", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); 4669 Matcher matcher = pattern.matcher(body); 4670 StringBuffer replaceBuffer = new StringBuffer(); 4671 while (matcher.find()) { 4672 String condition = matcher.group().replace("\r\n", "\n").replace("'", "\\\\'") 4673 .replace("\n", "\\\\n'\n+'").replace("`", "'").replace("$", "RDS_CHAR_DOLLAR"); 4674 matcher.appendReplacement(replaceBuffer, condition); 4675 } 4676 matcher.appendTail(replaceBuffer); 4677 body = replaceBuffer.toString().replace("RDS_CHAR_DOLLAR", "$"); 4678 } 4679 if (quote && body.indexOf("'") != -1) { 4680 body = body.replace("''", "'"); 4681 } 4682 buffer.append(body); 4683 buffer.append("})("); 4684 for (int i = 0; i < args.length; i++) { 4685 String type = argMap.get(args[i]); 4686 if (type.equalsIgnoreCase("VARCHAR")) { 4687 buffer.append("'pseudo'"); 4688 } else if (type.equalsIgnoreCase("STRING")) { 4689 buffer.append("'pseudo'"); 4690 } else if (type.equalsIgnoreCase("CHAR")) { 4691 buffer.append("'pseudo'"); 4692 } else if (type.equalsIgnoreCase("CHARACTER")) { 4693 buffer.append("'pseudo'"); 4694 } else if (type.equalsIgnoreCase("TEXT")) { 4695 buffer.append("'pseudo'"); 4696 } else if (type.equalsIgnoreCase("BINARY")) { 4697 buffer.append("'pseudo'"); 4698 } else if (type.equalsIgnoreCase("VARBINARY")) { 4699 buffer.append("'pseudo'"); 4700 } else if (type.equalsIgnoreCase("BOOLEAN")) { 4701 buffer.append(true); 4702 } else if (type.equalsIgnoreCase("FLOAT")) { 4703 buffer.append("1.0"); 4704 } else if (type.equalsIgnoreCase("FLOAT4")) { 4705 buffer.append("1.0"); 4706 } else if (type.equalsIgnoreCase("FLOAT8")) { 4707 buffer.append("1.0"); 4708 } else if (type.equalsIgnoreCase("DOUBLE")) { 4709 buffer.append("1.0"); 4710 } else if (type.equalsIgnoreCase("DOUBLE PRECISION")) { 4711 buffer.append("1.0"); 4712 } else if (type.equalsIgnoreCase("REAL")) { 4713 buffer.append("1.0"); 4714 } else if (type.equalsIgnoreCase("NUMBER")) { 4715 buffer.append("1.0"); 4716 } else if (type.equalsIgnoreCase("DECIMAL")) { 4717 buffer.append("1.0"); 4718 } else if (type.equalsIgnoreCase("NUMERIC")) { 4719 buffer.append("1.0"); 4720 } else if (type.equalsIgnoreCase("INT")) { 4721 buffer.append("1"); 4722 } else if (type.equalsIgnoreCase("INTEGER")) { 4723 buffer.append("1"); 4724 } else if (type.equalsIgnoreCase("BIGINT")) { 4725 buffer.append("1"); 4726 } else if (type.equalsIgnoreCase("SMALLINT")) { 4727 buffer.append("1"); 4728 } else if (type.equalsIgnoreCase("DATE")) { 4729 buffer.append("new Date()"); 4730 } else if (type.equalsIgnoreCase("DATETIME")) { 4731 buffer.append("new Date()"); 4732 } else if (type.equalsIgnoreCase("TIME")) { 4733 buffer.append("new Date()"); 4734 } else if (type.equalsIgnoreCase("TIMESTAMP")) { 4735 buffer.append("new Date()"); 4736 } else if (type.equalsIgnoreCase("TIMESTAMP_LTZ")) { 4737 buffer.append("new Date()"); 4738 } else if (type.equalsIgnoreCase("TIMESTAMP_NTZ")) { 4739 buffer.append("new Date()"); 4740 } else if (type.equalsIgnoreCase("TIMESTAMP_TZ")) { 4741 buffer.append("new Date()"); 4742 } else if (type.equalsIgnoreCase("VARIANT")) { 4743 buffer.append("{}"); 4744 } else if (type.equalsIgnoreCase("OBJECT")) { 4745 buffer.append("{}"); 4746 } else if (type.equalsIgnoreCase("ARRAY")) { 4747 buffer.append("[]"); 4748 } else if (type.equalsIgnoreCase("GEOGRAPHY")) { 4749 buffer.append("{}"); 4750 } 4751 if (i < args.length - 1) { 4752 buffer.append(","); 4753 } 4754 } 4755 buffer.append(");"); 4756 4757 try { 4758 ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); 4759 ScriptEngine nashorn = scriptEngineManager.getEngineByName("nashorn"); 4760 nashorn.put("analyzer", this); 4761 nashorn.eval(new InputStreamReader( 4762 getClass().getResourceAsStream("/gudusoft/gsqlparser/parser/snowflake/snowflake.js"))); 4763 nashorn.eval(new StringReader(buffer.toString())); 4764 } catch (ScriptException e) { 4765 TGSqlParser sqlparser = new TGSqlParser(option.getVendor()); 4766 sqlparser.sqltext = body; 4767 int result = sqlparser.parse(); 4768 if (result == 0) { 4769 for (int i = 0; i < sqlparser.sqlstatements.size(); i++) { 4770 analyzeCustomSqlStmt(sqlparser.sqlstatements.get(i)); 4771 } 4772 return; 4773 } 4774 ErrorInfo errorInfo = new ErrorInfo(); 4775 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 4776 errorInfo.setErrorMessage("Invoke script error: " + e.getMessage()); 4777 errorInfo.setStartPosition(new Pair3<Long, Long, String>(procedure.getStartToken().lineNo, 4778 procedure.getStartToken().columnNo, ModelBindingManager.getGlobalHash())); 4779 errorInfo.setEndPosition(new Pair3<Long, Long, String>(procedure.getEndToken().lineNo, 4780 procedure.getEndToken().columnNo + procedure.getEndToken().getAstext().length(), 4781 ModelBindingManager.getGlobalHash())); 4782 errorInfos.add(errorInfo); 4783 } 4784 } 4785 4786 private void analyzeHiveLoadStmt(THiveLoad stmt) { 4787 if (stmt.getPath() != null && stmt.getTable() != null) { 4788 Table uriFile = modelFactory.createTableByName(stmt.getPath(), true); 4789 uriFile.setPath(true); 4790 uriFile.setCreateTable(true); 4791 TObjectName fileUri = new TObjectName(); 4792 fileUri.setString("uri=" + stmt.getPath()); 4793 TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri); 4794 4795 Table tableModel = modelFactory.createTable(stmt.getTable()); 4796 Process process = modelFactory.createProcess(stmt); 4797 tableModel.addProcess(process); 4798 4799 TPartitionExtensionClause p = stmt.getTable().getPartitionExtensionClause(); 4800 if (p.getKeyValues() != null && p.getKeyValues().size() > 0) { 4801 for (int i = 0; i < p.getKeyValues().size(); i++) { 4802 TExpression expression = p.getKeyValues().getExpression(i); 4803 if (expression.getLeftOperand().getExpressionType() == EExpressionType.simple_object_name_t) { 4804 modelFactory.createTableColumn(tableModel, expression.getLeftOperand().getObjectOperand(), 4805 true); 4806 } 4807 } 4808 } 4809 4810 for (int j = 0; j < tableModel.getColumns().size(); j++) { 4811 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 4812 relation.addSource(new TableColumnRelationshipElement(fileUriColumn)); 4813 relation.setTarget(new TableColumnRelationshipElement(tableModel.getColumns().get(j))); 4814 relation.setProcess(process); 4815 } 4816 } 4817 } 4818 4819 private void analyzeLoadDataStmt(TLoadDataStmt stmt) { 4820 4821 } 4822 4823 private void analyzeUnloadStmt(TUnloadStmt unloadStmt) { 4824 if (unloadStmt.getSelectSqlStatement() != null && unloadStmt.getS3() != null) { 4825 4826 Table uriFile = modelFactory.createTableByName(unloadStmt.getS3(), true); 4827 uriFile.setPath(true); 4828 uriFile.setCreateTable(true); 4829 TObjectName fileUri = new TObjectName(); 4830 fileUri.setString("uri=" + unloadStmt.getS3()); 4831 TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri); 4832 4833 Process process = modelFactory.createProcess(unloadStmt); 4834 uriFile.addProcess(process); 4835 4836 TCustomSqlStatement stmt = unloadStmt.getSelectSqlStatement(); 4837 analyzeCustomSqlStmt(stmt); 4838 if (stmt instanceof TSelectSqlStatement) { 4839 TSelectSqlStatement select = (TSelectSqlStatement) stmt; 4840 ResultSet resultSetModel = (ResultSet) modelManager.getModel(select); 4841 if (resultSetModel != null) { 4842 for (int j = 0; j < resultSetModel.getColumns().size(); j++) { 4843 ResultColumn resultColumn = resultSetModel.getColumns().get(j); 4844 if (resultColumn.hasStarLinkColumn() 4845 && resultColumn.getStarLinkColumnNames().size() > 0) { 4846 for (int k = 0; k < resultColumn.getStarLinkColumnNames().size(); k++) { 4847 ResultColumn expandStarColumn = modelFactory.createResultColumn(resultSetModel, 4848 resultColumn.getStarLinkColumnName(k), false); 4849 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 4850 dataflowRelation.setEffectType(EffectType.unload); 4851 dataflowRelation 4852 .addSource(new ResultColumnRelationshipElement(expandStarColumn)); 4853 dataflowRelation.setTarget(new TableColumnRelationshipElement(fileUriColumn)); 4854 dataflowRelation.setProcess(process); 4855 } 4856 } 4857 if (!resultColumn.hasStarLinkColumn() || resultColumn.isShowStar()) { 4858 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 4859 dataflowRelation.setEffectType(EffectType.unload); 4860 dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn)); 4861 dataflowRelation.setTarget(new TableColumnRelationshipElement(fileUriColumn)); 4862 dataflowRelation.setProcess(process); 4863 } 4864 } 4865 } 4866 } 4867 } 4868 4869 } 4870 4871 private void analyzeCopyIntoStmt(TSnowflakeCopyIntoStmt stmt) { 4872 if (stmt.getTableName() != null) { 4873 if (stmt.getStageLocation() != null) { 4874 Table intoTable = modelManager 4875 .getTableByName(DlineageUtil.getTableFullName(stmt.getTableName().toString())); 4876 if (intoTable == null) { 4877 intoTable = modelFactory.createTableByName(stmt.getTableName(), false); 4878 TObjectName starColumn = new TObjectName(); 4879 starColumn.setString("*"); 4880 TableColumn column = modelFactory.createTableColumn(intoTable, starColumn, false); 4881 if (column != null) { 4882 column.setExpandStar(false); 4883 column.setPseduo(true); 4884 } 4885 } 4886 Process process = modelFactory.createProcess(stmt); 4887 intoTable.addProcess(process); 4888 4889 TObjectName stageName = stmt.getStageLocation().getStageName(); 4890 if (stageName == null || stmt.getStageLocation().getTableName() != null) { 4891 stageName = stmt.getStageLocation().getTableName(); 4892 } 4893 if (stageName != null) { 4894 String stageFullName = DlineageUtil.getTableFullName(stageName.toString()); 4895 Table stage = modelManager.getTableByName(stageFullName); 4896 if (stage == null) { 4897 stage = modelFactory.createStage(stageName); 4898 stage.setCreateTable(true); 4899 stage.setStage(true); 4900 String stagePath = stmt.getStageLocation().getPath() == null ? null 4901 : stmt.getStageLocation().getPath().toString(); 4902 if (stagePath != null) { 4903 stage.setLocation(stagePath); 4904 TObjectName location = new TObjectName(); 4905 location.setString(stagePath); 4906 modelFactory.createStageLocation(stage, location); 4907 } else { 4908 stage.setLocation("unknownPath"); 4909 TObjectName location = new TObjectName(); 4910 location.setString("unknownPath"); 4911 modelFactory.createStageLocation(stage, location); 4912 } 4913 } 4914 4915 if (stage != null && intoTable != null) { 4916 if (intoTable != null && !intoTable.getColumns().isEmpty() && !stage.getColumns().isEmpty()) { 4917 for (int i = 0; i < intoTable.getColumns().size(); i++) { 4918 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 4919 relation.addSource(new TableColumnRelationshipElement(stage.getColumns().get(0))); 4920 relation.setTarget(new TableColumnRelationshipElement(intoTable.getColumns().get(i))); 4921 relation.setProcess(process); 4922 } 4923 } 4924 } 4925 } else if (stmt.getStageLocation().getExternalLocation() != null) { 4926 Table pathModel = modelFactory.createTableByName(stmt.getStageLocation().getExternalLocation(), 4927 true); 4928 pathModel.setPath(true); 4929 pathModel.setCreateTable(true); 4930 TableColumn fileUriColumn = modelFactory.createFileUri(pathModel, 4931 stmt.getStageLocation().getExternalLocation()); 4932 if (intoTable != null) { 4933 if (intoTable != null && !intoTable.getColumns().isEmpty()) { 4934 for (int i = 0; i < intoTable.getColumns().size(); i++) { 4935 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 4936 relation.addSource(new TableColumnRelationshipElement(fileUriColumn)); 4937 relation.setTarget(new TableColumnRelationshipElement(intoTable.getColumns().get(i))); 4938 relation.setProcess(process); 4939 } 4940 } 4941 } 4942 } 4943 } 4944 else if (stmt.getSubQuery() != null) { 4945 analyzeSelectStmt(stmt.getSubQuery()); 4946 4947 Table intoTable = modelManager 4948 .getTableByName(DlineageUtil.getTableFullName(stmt.getTableName().toString())); 4949 if (intoTable == null) { 4950 intoTable = modelFactory.createTableByName(stmt.getTableName(), false); 4951 TObjectName starColumn = new TObjectName(); 4952 starColumn.setString("*"); 4953 TableColumn column = modelFactory.createTableColumn(intoTable, starColumn, false); 4954 if (column != null) { 4955 column.setExpandStar(true); 4956 column.setPseduo(true); 4957 } 4958 4959 Process process = modelFactory.createProcess(stmt); 4960 intoTable.addProcess(process); 4961 4962 ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubQuery()); 4963 if (resultSetModel != null && column != null) { 4964 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 4965 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 4966 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 4967 dataflowRelation.setEffectType(EffectType.copy); 4968 dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn)); 4969 dataflowRelation.setTarget(new TableColumnRelationshipElement(column)); 4970 dataflowRelation.setProcess(process); 4971 } 4972 } 4973 } 4974 } 4975 } 4976 } 4977 4978 private void analyzeRedshiftCopyStmt(TRedshiftCopy stmt) { 4979 if (stmt.getTableName() != null && stmt.getFromSource() != null) { 4980 4981 Table intoTable = modelManager 4982 .getTableByName(DlineageUtil.getTableFullName(stmt.getTableName().toString())); 4983 if (intoTable == null) { 4984 intoTable = modelFactory.createTableByName(stmt.getTableName(), false); 4985 if (stmt.getColumnList() == null || stmt.getColumnList().size() == 0) { 4986 TObjectName starColumn = new TObjectName(); 4987 starColumn.setString("*"); 4988 TableColumn column = modelFactory.createTableColumn(intoTable, starColumn, false); 4989 if (column != null) { 4990 column.setExpandStar(false); 4991 column.setPseduo(true); 4992 } 4993 } else { 4994 for (TObjectName columnName : stmt.getColumnList()) { 4995 modelFactory.createTableColumn(intoTable, columnName, true); 4996 } 4997 } 4998 } 4999 Process process = modelFactory.createProcess(stmt); 5000 intoTable.addProcess(process); 5001 5002 if (stmt.getFromSource() != null) { 5003 Table pathModel = modelFactory.createTableByName(stmt.getFromSource(), true); 5004 pathModel.setPath(true); 5005 pathModel.setCreateTable(true); 5006 TObjectName fileUri = new TObjectName(); 5007 fileUri.setString(stmt.getFromSource()); 5008 TableColumn fileUriColumn = modelFactory.createFileUri(pathModel, fileUri); 5009 if (intoTable != null) { 5010 if (intoTable != null && !intoTable.getColumns().isEmpty()) { 5011 for (int i = 0; i < intoTable.getColumns().size(); i++) { 5012 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5013 relation.addSource(new TableColumnRelationshipElement(fileUriColumn)); 5014 relation.setTarget(new TableColumnRelationshipElement(intoTable.getColumns().get(i))); 5015 relation.setProcess(process); 5016 } 5017 } 5018 } 5019 } 5020 } 5021 } 5022 5023 private void analyzeCreateIndexExpressionOperand(TExpression expr, Table tableModel){ 5024 if(expr == null) return; 5025 Deque<TExpression> stack = new ArrayDeque<>(); 5026 stack.push(expr); 5027 while (!stack.isEmpty()) { 5028 TExpression current = stack.pop(); 5029 if (current == null) continue; 5030 TObjectName columnObj = current.getObjectOperand(); 5031 if (columnObj != null) { 5032 TableColumn tableConstraint = modelFactory.createTableColumn(tableModel, columnObj, true); 5033 tableConstraint.setIndexKey(true); 5034 } else { 5035 if (current.getRightOperand() != null) { 5036 stack.push(current.getRightOperand()); 5037 } 5038 if (current.getLeftOperand() != null) { 5039 stack.push(current.getLeftOperand()); 5040 } 5041 } 5042 } 5043 } 5044 private void analyzeCreateIndexStageStmt(TCreateIndexSqlStatement stmt) { 5045 if(stmt.getTableName() == null){ 5046 return; 5047 } 5048 Table tableModel = modelFactory.createTableByName(stmt.getTableName()); 5049 TOrderByItemList columns = stmt.getColumnNameList(); 5050 if(columns!=null) { 5051 for (int i = 0; i < columns.size(); i++) { 5052 TExpression expr = columns.getOrderByItem(i).getSortKey(); 5053 analyzeCreateIndexExpressionOperand(expr, tableModel); 5054 } 5055 } 5056 } 5057 5058 private void analyzeCreateSynonymStmt(TCreateSynonymStmt stmt) { 5059 TObjectName sourceTableName = stmt.getForName(); 5060 if(sourceTableName == null) { 5061 return; 5062 } 5063 TCustomSqlStatement createView = viewDDLMap 5064 .get(DlineageUtil.getTableFullName(sourceTableName.toString())); 5065 if (createView != null) { 5066 analyzeCustomSqlStmt(createView); 5067 } 5068 Table sourceTableModel = modelFactory.createTableByName(sourceTableName); 5069 Process process = modelFactory.createProcess(stmt); 5070 sourceTableModel.addProcess(process); 5071 if(stmt.getSynonymName()!=null) { 5072 Table synonymTableModel = modelFactory.createTableByName(stmt.getSynonymName()); 5073 synonymTableModel.setSubType(SubType.synonym); 5074 if(sourceTableModel.isCreateTable()) { 5075 synonymTableModel.setCreateTable(true); 5076 for(TableColumn sourceTableColumn: sourceTableModel.getColumns()) { 5077 TObjectName columnName = new TObjectName(); 5078 columnName.setString(sourceTableColumn.getName()); 5079 TableColumn synonymTableColumn = new TableColumn(synonymTableModel, columnName); 5080 synonymTableModel.addColumn(synonymTableColumn); 5081 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5082 relation.setEffectType(EffectType.create_synonym); 5083 relation.setTarget(new TableColumnRelationshipElement(synonymTableColumn)); 5084 relation.addSource(new TableColumnRelationshipElement(sourceTableColumn)); 5085 relation.setProcess(process); 5086 } 5087 } 5088 else { 5089 TObjectName synonymStarColumn = new TObjectName(); 5090 synonymStarColumn.setString("*"); 5091 TableColumn synonymTableStarColumn = modelFactory.createTableColumn(synonymTableModel, 5092 synonymStarColumn, true); 5093 TObjectName sourceStarColumn = new TObjectName(); 5094 sourceStarColumn.setString("*"); 5095 TableColumn sourceTableStarColumn = modelFactory.createTableColumn(sourceTableModel, sourceStarColumn, true); 5096 5097 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5098 relation.setEffectType(EffectType.create_synonym); 5099 relation.setTarget(new TableColumnRelationshipElement(synonymTableStarColumn)); 5100 relation.addSource(new TableColumnRelationshipElement(sourceTableStarColumn)); 5101 relation.setProcess(process); 5102 } 5103 } 5104 } 5105 5106 /** 5107 * For every Table model that maps to a {@link TSQLSynonyms} in the current 5108 * {@link #sqlenv}, materialize the synonym's base table as a separate Table 5109 * model and emit per-column {@code fdd}/{@code synonym} relations from the 5110 * synonym's columns to the base table's matching columns. Lets lineage flow 5111 * through synonyms defined in the metadata SQLEnv (e.g. loaded via 5112 * {@code TDDLSQLEnv} or sqlflow metadata) the same way it does for 5113 * {@code CREATE SYNONYM} DDL inside the analyzed script. 5114 */ 5115 private void materializeSqlEnvSynonyms() { 5116 if (sqlenv == null) { 5117 return; 5118 } 5119 List<Table> snapshot = new ArrayList<Table>(modelManager.getTablesByName()); 5120 5121 Map<String, TSQLSynonyms> synonymCache = new HashMap<>(); 5122 List<TSQLCatalog> catalogs = sqlenv.getCatalogList(); 5123 if (catalogs != null) { 5124 for (TSQLCatalog catalog : catalogs) { 5125 if (catalog == null) { 5126 continue; 5127 } 5128 List<TSQLSchema> schemas = catalog.getSchemaList(); 5129 if (schemas == null) { 5130 continue; 5131 } 5132 for (TSQLSchema schema : schemas) { 5133 if (schema == null) { 5134 continue; 5135 } 5136 List<TSQLSchemaObject> schemaObjects = schema.getSchemaObjectList(); 5137 if (schemaObjects == null || schemaObjects.isEmpty()) { 5138 continue; 5139 } 5140 for (TSQLSchemaObject schemaObject : schemaObjects) { 5141 if (schemaObject instanceof TSQLSynonyms) { 5142 TSQLSynonyms synonym = (TSQLSynonyms) schemaObject; 5143 String qualifiedName = synonym.getQualifiedName(); 5144 String normalizedName = DlineageUtil.getIdentifierNormalTableName(qualifiedName); 5145 synonymCache.put(normalizedName, synonym); 5146 } 5147 } 5148 } 5149 } 5150 } 5151 5152 for (Table synonymTableModel : snapshot) { 5153 if (synonymTableModel == null) { 5154 continue; 5155 } 5156 if (SubType.synonym.equals(synonymTableModel.getSubType())) { 5157 continue; 5158 } 5159 String qualifiedName = ModelFactory.getQualifiedTableName(synonymTableModel); 5160 String normalizedName = DlineageUtil.getIdentifierNormalTableName(qualifiedName); 5161 TSQLSynonyms synonym = synonymCache.get(normalizedName); 5162 if (synonym == null) { 5163 continue; 5164 } 5165 5166 String baseSqlTableQualifiedName = synonym.getBaseTableQualifiedName(); 5167 if (baseSqlTableQualifiedName == null) { 5168 continue; 5169 } 5170 5171 synonymTableModel.setSubType(SubType.synonym); 5172 5173 TObjectName baseObjectName = new TObjectName(); 5174 baseObjectName.setString(baseSqlTableQualifiedName); 5175 Table baseTableModel = modelFactory.createTableByName(baseObjectName); 5176 if (baseTableModel == null || baseTableModel == synonymTableModel) { 5177 continue; 5178 } 5179 5180 for (TableColumn synonymColumn : new ArrayList<TableColumn>(synonymTableModel.getColumns())) { 5181 String colName = synonymColumn.getName(); 5182 if (SQLUtil.isEmpty(colName) || "*".equals(colName)) { 5183 continue; 5184 } 5185 TableColumn baseColumn = null; 5186 for (TableColumn bc : baseTableModel.getColumns()) { 5187 if (bc.getName() != null && bc.getName().equalsIgnoreCase(colName)) { 5188 baseColumn = bc; 5189 break; 5190 } 5191 } 5192 if (baseColumn == null) { 5193 TObjectName columnName = new TObjectName(); 5194 columnName.setString(colName); 5195 baseColumn = new TableColumn(baseTableModel, columnName); 5196 baseTableModel.addColumn(baseColumn); 5197 } 5198 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5199 relation.setEffectType(EffectType.synonym); 5200 relation.setTarget(new TableColumnRelationshipElement(synonymColumn)); 5201 relation.addSource(new TableColumnRelationshipElement(baseColumn)); 5202 } 5203 } 5204 } 5205 5206 private void analyzeRenameStmt(TRenameStmt stmt) { 5207 TObjectName oldTableName = stmt.getOldName(); 5208 TObjectName newTableName = stmt.getNewName(); 5209 5210 Table oldNameTableModel = modelFactory.createTableByName(oldTableName); 5211 TObjectName oldStarColumn = new TObjectName(); 5212 oldStarColumn.setString("*"); 5213 TableColumn oldTableStarColumn = modelFactory.createTableColumn(oldNameTableModel, oldStarColumn, true); 5214 5215 Table newNameTableModel = modelFactory.createTableByName(newTableName); 5216 TObjectName newStarColumn = new TObjectName(); 5217 newStarColumn.setString("*"); 5218 TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, newStarColumn, true); 5219 5220 Process process = modelFactory.createProcess(stmt); 5221 newNameTableModel.addProcess(process); 5222 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5223 relation.setEffectType( EffectType.rename_table); 5224 relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn)); 5225 relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn)); 5226 relation.setProcess(process); 5227 5228 if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) { 5229 oldTableStarColumn.setShowStar(false); 5230 relation.setShowStarRelation(false); 5231 } 5232 5233 if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) { 5234 newTableStarColumn.setShowStar(false); 5235 relation.setShowStarRelation(false); 5236 } 5237 } 5238 5239 private void analyzeAlterTableStmt(TAlterTableStatement stmt) { 5240 TTable oldNameTable = stmt.getTargetTable(); 5241 if (oldNameTable == null) { 5242 return; 5243 } 5244 5245 Table oldNameTableModel = modelFactory.createTable(oldNameTable); 5246 TObjectName oldStarColumn = new TObjectName(); 5247 oldStarColumn.setString("*"); 5248 TableColumn oldTableStarColumn = modelFactory.createTableColumn(oldNameTableModel, oldStarColumn, true); 5249 5250 for (int i = 0; stmt.getAlterTableOptionList() != null && i < stmt.getAlterTableOptionList().size(); i++) { 5251 TAlterTableOption option = stmt.getAlterTableOptionList().getAlterTableOption(i); 5252 if (option.getOptionType() == EAlterTableOptionType.RenameTable 5253 || option.getOptionType() == EAlterTableOptionType.swapWith) { 5254 TObjectName newTableName = option.getNewTableName(); 5255 Stack<TParseTreeNode> list = newTableName.getStartToken().getNodesStartFromThisToken(); 5256 boolean containsTable = false; 5257 for (int j = 0; j < list.size(); j++) { 5258 if (list.get(j) instanceof TTable) { 5259 TTable newTableTable = (TTable) list.get(j); 5260 Table newNameTableModel = modelFactory.createTable(newTableTable); 5261 newNameTableModel.setStarStmt("rename_table"); 5262 5263 TObjectName newStarColumn = new TObjectName(); 5264 newStarColumn.setString("*"); 5265 TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, 5266 newStarColumn, true); 5267 5268 Process process = modelFactory.createProcess(stmt); 5269 newNameTableModel.addProcess(process); 5270 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5271 relation.setEffectType( 5272 option.getOptionType() == EAlterTableOptionType.RenameTable ? EffectType.rename_table 5273 : EffectType.swap_table); 5274 if (option.getOptionType() == EAlterTableOptionType.RenameTable) { 5275 relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn)); 5276 relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn)); 5277 } else if (option.getOptionType() == EAlterTableOptionType.swapWith) { 5278 relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn)); 5279 relation.addSource(new TableColumnRelationshipElement(newTableStarColumn)); 5280 } 5281 relation.setProcess(process); 5282 containsTable = true; 5283 5284 if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) { 5285 oldTableStarColumn.setShowStar(false); 5286 relation.setShowStarRelation(false); 5287 } 5288 5289 if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) { 5290 newTableStarColumn.setShowStar(false); 5291 relation.setShowStarRelation(false); 5292 } 5293 } 5294 } 5295 if (!containsTable) { 5296 Table newNameTableModel = modelFactory.createTableByName(newTableName); 5297 newNameTableModel.setStarStmt("rename_table"); 5298 TObjectName newStarColumn = new TObjectName(); 5299 newStarColumn.setString("*"); 5300 TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, newStarColumn, 5301 true); 5302 5303 Process process = modelFactory.createProcess(stmt); 5304 newNameTableModel.addProcess(process); 5305 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5306 relation.setEffectType( 5307 option.getOptionType() == EAlterTableOptionType.RenameTable ? EffectType.rename_table 5308 : EffectType.swap_table); 5309 if (option.getOptionType() == EAlterTableOptionType.RenameTable) { 5310 relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn)); 5311 relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn)); 5312 } else if (option.getOptionType() == EAlterTableOptionType.swapWith) { 5313 relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn)); 5314 relation.addSource(new TableColumnRelationshipElement(newTableStarColumn)); 5315 } 5316 relation.setProcess(process); 5317 if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) { 5318 oldTableStarColumn.setShowStar(false); 5319 relation.setShowStarRelation(false); 5320 } 5321 5322 if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) { 5323 newTableStarColumn.setShowStar(false); 5324 relation.setShowStarRelation(false); 5325 } 5326 5327 } 5328 } 5329 else if (option.getOptionType() == EAlterTableOptionType.appendFrom) { 5330 TObjectName newTableName = option.getSourceTableName(); 5331 Stack<TParseTreeNode> list = newTableName.getStartToken().getNodesStartFromThisToken(); 5332 boolean containsTable = false; 5333 for (int j = 0; j < list.size(); j++) { 5334 if (list.get(j) instanceof TTable) { 5335 TTable newTableTable = (TTable) list.get(j); 5336 Table newNameTableModel = modelFactory.createTable(newTableTable); 5337 newNameTableModel.setStarStmt("append_from"); 5338 5339 TObjectName newStarColumn = new TObjectName(); 5340 newStarColumn.setString("*"); 5341 TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, 5342 newStarColumn, true); 5343 5344 Process process = modelFactory.createProcess(stmt); 5345 newNameTableModel.addProcess(process); 5346 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5347 relation.setEffectType(EffectType.append_from); 5348 relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn)); 5349 relation.addSource(new TableColumnRelationshipElement(newTableStarColumn)); 5350 relation.setProcess(process); 5351 containsTable = true; 5352 5353 if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) { 5354 oldTableStarColumn.setShowStar(false); 5355 relation.setShowStarRelation(false); 5356 } 5357 5358 if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) { 5359 newTableStarColumn.setShowStar(false); 5360 relation.setShowStarRelation(false); 5361 } 5362 } 5363 } 5364 if (!containsTable) { 5365 Table newNameTableModel = modelFactory.createTableByName(newTableName); 5366 newNameTableModel.setStarStmt("append_from"); 5367 TObjectName newStarColumn = new TObjectName(); 5368 newStarColumn.setString("*"); 5369 TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, newStarColumn, 5370 true); 5371 5372 Process process = modelFactory.createProcess(stmt); 5373 newNameTableModel.addProcess(process); 5374 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5375 relation.setEffectType(EffectType.append_from); 5376 relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn)); 5377 relation.addSource(new TableColumnRelationshipElement(newTableStarColumn)); 5378 relation.setProcess(process); 5379 if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) { 5380 oldTableStarColumn.setShowStar(false); 5381 relation.setShowStarRelation(false); 5382 } 5383 5384 if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) { 5385 newTableStarColumn.setShowStar(false); 5386 relation.setShowStarRelation(false); 5387 } 5388 5389 } 5390 } 5391 else if (option.getOptionType() == EAlterTableOptionType.exchangePartition) { 5392 TObjectName newTableName = option.getNewTableName(); 5393 Stack<TParseTreeNode> list = newTableName.getStartToken().getNodesStartFromThisToken(); 5394 boolean containsTable = false; 5395 for (int j = 0; j < list.size(); j++) { 5396 if (list.get(j) instanceof TTable) { 5397 TTable newTableTable = (TTable) list.get(j); 5398 Table newNameTableModel = modelFactory.createTable(newTableTable); 5399 newNameTableModel.setStarStmt("exchange_partition"); 5400 5401 TObjectName newStarColumn = new TObjectName(); 5402 newStarColumn.setString("*"); 5403 TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, 5404 newStarColumn, true); 5405 5406 Process process = modelFactory.createProcess(stmt); 5407 newNameTableModel.addProcess(process); 5408 { 5409 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5410 relation.setEffectType(EffectType.exchange_partition); 5411 relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn)); 5412 relation.addSource(new TableColumnRelationshipElement(newTableStarColumn)); 5413 relation.setProcess(process); 5414 if (option.getPartitionName() != null) { 5415 relation.setPartition(option.getPartitionName().toString()); 5416 } 5417 if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) { 5418 oldTableStarColumn.setShowStar(false); 5419 relation.setShowStarRelation(false); 5420 } 5421 5422 if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) { 5423 newTableStarColumn.setShowStar(false); 5424 relation.setShowStarRelation(false); 5425 } 5426 } 5427 { 5428 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5429 relation.setEffectType(EffectType.exchange_partition); 5430 relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn)); 5431 relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn)); 5432 relation.setProcess(process); 5433 if (option.getPartitionName() != null) { 5434 relation.setPartition(option.getPartitionName().toString()); 5435 } 5436 if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) { 5437 oldTableStarColumn.setShowStar(false); 5438 relation.setShowStarRelation(false); 5439 } 5440 5441 if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) { 5442 newTableStarColumn.setShowStar(false); 5443 relation.setShowStarRelation(false); 5444 } 5445 } 5446 containsTable = true; 5447 } 5448 } 5449 if (!containsTable) { 5450 Table newNameTableModel = modelFactory.createTableByName(newTableName); 5451 newNameTableModel.setStarStmt("exchange_partition"); 5452 TObjectName newStarColumn = new TObjectName(); 5453 newStarColumn.setString("*"); 5454 TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, newStarColumn, 5455 true); 5456 5457 Process process = modelFactory.createProcess(stmt); 5458 newNameTableModel.addProcess(process); 5459 { 5460 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5461 relation.setEffectType(EffectType.exchange_partition); 5462 relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn)); 5463 relation.addSource(new TableColumnRelationshipElement(newTableStarColumn)); 5464 if (option.getPartitionName() != null) { 5465 relation.setPartition(option.getPartitionName().toString()); 5466 } 5467 relation.setProcess(process); 5468 if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) { 5469 oldTableStarColumn.setShowStar(false); 5470 relation.setShowStarRelation(false); 5471 } 5472 5473 if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) { 5474 newTableStarColumn.setShowStar(false); 5475 relation.setShowStarRelation(false); 5476 } 5477 } 5478 { 5479 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5480 relation.setEffectType(EffectType.exchange_partition); 5481 relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn)); 5482 relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn)); 5483 if (option.getPartitionName() != null) { 5484 relation.setPartition(option.getPartitionName().toString()); 5485 } 5486 relation.setProcess(process); 5487 if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) { 5488 oldTableStarColumn.setShowStar(false); 5489 relation.setShowStarRelation(false); 5490 } 5491 5492 if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) { 5493 newTableStarColumn.setShowStar(false); 5494 relation.setShowStarRelation(false); 5495 } 5496 } 5497 } 5498 } 5499 else if(option.getOptionType() == EAlterTableOptionType.setLocation) { 5500 TObjectName location = option.getTableLocation(); 5501 Process process = modelFactory.createProcess(stmt); 5502 process.setType("Set Table Location"); 5503 oldNameTableModel.addProcess(process); 5504 Table uriFile = modelFactory.createTableByName(location, true); 5505 uriFile.setPath(true); 5506 for (int j = 0; j < oldNameTableModel.getColumns().size(); j++) { 5507 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5508 TObjectName fileUri = new TObjectName(); 5509 fileUri.setString("*"); 5510 TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri); 5511 relation.addSource(new TableColumnRelationshipElement(fileUriColumn)); 5512 relation.setTarget(new TableColumnRelationshipElement(oldNameTableModel.getColumns().get(j))); 5513 relation.setProcess(process); 5514 } 5515 } 5516 else if (option.getOptionType() == EAlterTableOptionType.AddColumn 5517 || option.getOptionType() == EAlterTableOptionType.addColumnIfNotExists) { 5518 if (option.getColumnDefinitionList() != null) { 5519 for (TColumnDefinition column : option.getColumnDefinitionList()) { 5520 if (column != null && column.getColumnName() != null) { 5521 TableColumn tableColumn = modelFactory.createTableColumn(oldNameTableModel, column.getColumnName(), true); 5522 if(this.option.getAnalyzeMode() == AnalyzeMode.crud) { 5523 CrudRelationship crudRelationship = modelFactory.createCrudRelation(); 5524 crudRelationship.setTarget(new TableColumnRelationshipElement(tableColumn)); 5525 crudRelationship.setEffectType(EffectType.add_table_column); 5526 } 5527 } 5528 } 5529 } 5530 } 5531 else if (option.getOptionType() == EAlterTableOptionType.DropColumn && this.option.getAnalyzeMode() == AnalyzeMode.crud) { 5532 if (option.getColumnNameList() != null) { 5533 for (TObjectName column : option.getColumnNameList()) { 5534 TableColumn tableColumn = modelFactory.createTableColumn(oldNameTableModel, column, true); 5535 CrudRelationship crudRelationship = modelFactory.createCrudRelation(); 5536 crudRelationship.setTarget(new TableColumnRelationshipElement(tableColumn)); 5537 crudRelationship.setEffectType(EffectType.drop_table_column); 5538 } 5539 } 5540 } 5541 else if(option.getOptionType() == EAlterTableOptionType.AddConstraint || option.getOptionType() == EAlterTableOptionType.AddConstraintFK 5542 || option.getOptionType() == EAlterTableOptionType.AddConstraintPK || option.getOptionType() == EAlterTableOptionType.AddConstraintUnique 5543 || option.getOptionType() == EAlterTableOptionType.AddConstraintIndex){ 5544 if (option.getTableConstraint() != null) { 5545 TConstraint alertTableConstraint = option.getTableConstraint(); 5546 TPTNodeList<TColumnWithSortOrder> keyNames = alertTableConstraint.getColumnList(); 5547 if (keyNames == null) { 5548 continue; 5549 } 5550 for (int k = 0; k < keyNames.size(); k++) { 5551 TObjectName keyName = keyNames.getElement(k).getColumnName(); 5552 TObjectName referencedTableName = alertTableConstraint.getReferencedObject(); 5553 Table tableModel = modelFactory.createTableByName(stmt.getTableName()); 5554 TableColumn tableConstraint = modelFactory.createTableColumn(tableModel, keyName, true); 5555 if(alertTableConstraint.getConstraint_type() == EConstraintType.primary_key){ 5556 tableConstraint.setPrimaryKey(true); 5557 } 5558 else if(alertTableConstraint.getConstraint_type() == EConstraintType.table_index){ 5559 tableConstraint.setIndexKey(true); 5560 } 5561 else if(alertTableConstraint.getConstraint_type() == EConstraintType.unique){ 5562 tableConstraint.setUnqiueKey(true); 5563 } 5564 else if (alertTableConstraint.getConstraint_type() == EConstraintType.foreign_key) { 5565 tableConstraint.setForeignKey(true); 5566 Table referencedTable = modelManager.getTableByName(DlineageUtil.getTableFullName(referencedTableName.toString())); 5567 if (referencedTable == null) { 5568 referencedTable = modelFactory.createTableByName(referencedTableName); 5569 } 5570 TObjectNameList referencedTableColumns = alertTableConstraint.getReferencedColumnList(); 5571 if (referencedTableColumns != null) { 5572 for (int j = 0; j < referencedTableColumns.size(); j++) { 5573 TableColumn tableColumn = modelFactory.createTableColumn(referencedTable, 5574 referencedTableColumns.getObjectName(j), false); 5575 if (tableColumn != null) { 5576 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5577 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 5578 relation.setTarget(new TableColumnRelationshipElement(tableConstraint)); 5579 relation.setEffectType(EffectType.foreign_key); 5580 Process process = modelFactory.createProcess(stmt); 5581 relation.setProcess(process); 5582 if(this.option.isShowERDiagram()){ 5583 ERRelationship erRelation = modelFactory.createERRelation(); 5584 erRelation.addSource(new TableColumnRelationshipElement(tableColumn)); 5585 erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint)); 5586 } 5587 } 5588 } 5589 } 5590 else{ 5591 TableColumn tableColumn = modelFactory.createTableColumn(referencedTable, keyName, false); 5592 if (tableColumn != null) { 5593 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5594 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 5595 relation.setTarget(new TableColumnRelationshipElement(tableConstraint)); 5596 relation.setEffectType(EffectType.foreign_key); 5597 if(this.option.isShowERDiagram()){ 5598 ERRelationship erRelation = modelFactory.createERRelation(); 5599 erRelation.addSource(new TableColumnRelationshipElement(tableColumn)); 5600 erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint)); 5601 } 5602 } 5603 } 5604 } 5605 } 5606 } 5607 else if (option.getConstraintList() != null) { 5608 for(int iCons=0; iCons<option.getConstraintList().size(); iCons++){ 5609 TConstraint alertTableConstraint = option.getConstraintList().getConstraint(iCons); 5610 TPTNodeList<TColumnWithSortOrder> keyNames = alertTableConstraint.getColumnList(); 5611 if(keyNames != null){ 5612 for (int k = 0; k < keyNames.size(); k++) { 5613 TObjectName keyName = keyNames.getElement(k).getColumnName(); 5614 TObjectName referencedTableName = alertTableConstraint.getReferencedObject(); 5615 Table tableModel = modelFactory.createTableByName(stmt.getTableName()); 5616 TableColumn tableConstraint = modelFactory.createTableColumn(tableModel, keyName, true); 5617 if(alertTableConstraint.getConstraint_type() == EConstraintType.primary_key){ 5618 tableConstraint.setPrimaryKey(true); 5619 } 5620 else if(alertTableConstraint.getConstraint_type() == EConstraintType.table_index){ 5621 tableConstraint.setIndexKey(true); 5622 } 5623 else if(alertTableConstraint.getConstraint_type() == EConstraintType.unique){ 5624 tableConstraint.setUnqiueKey(true); 5625 } 5626 else if (alertTableConstraint.getConstraint_type() == EConstraintType.foreign_key) { 5627 tableConstraint.setForeignKey(true); 5628 Table referencedTable = modelManager.getTableByName(DlineageUtil.getTableFullName(referencedTableName.toString())); 5629 if (referencedTable == null) { 5630 referencedTable = modelFactory.createTableByName(referencedTableName); 5631 } 5632 TObjectNameList referencedTableColumns = alertTableConstraint.getReferencedColumnList(); 5633 if (referencedTableColumns != null) { 5634 for (int j = 0; j < referencedTableColumns.size(); j++) { 5635 TableColumn tableColumn = modelFactory.createTableColumn(referencedTable, 5636 referencedTableColumns.getObjectName(j), false); 5637 if (tableColumn != null) { 5638 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5639 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 5640 relation.setTarget(new TableColumnRelationshipElement(tableConstraint)); 5641 relation.setEffectType(EffectType.foreign_key); 5642 Process process = modelFactory.createProcess(stmt); 5643 relation.setProcess(process); 5644 if(this.option.isShowERDiagram()){ 5645 ERRelationship erRelation = modelFactory.createERRelation(); 5646 erRelation.addSource(new TableColumnRelationshipElement(tableColumn)); 5647 erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint)); 5648 } 5649 } 5650 } 5651 } 5652 else{ 5653 TableColumn tableColumn = modelFactory.createTableColumn(referencedTable, keyName, false); 5654 if (tableColumn != null) { 5655 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5656 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 5657 relation.setTarget(new TableColumnRelationshipElement(tableConstraint)); 5658 relation.setEffectType(EffectType.foreign_key); 5659 Process process = modelFactory.createProcess(stmt); 5660 relation.setProcess(process); 5661 if(this.option.isShowERDiagram()){ 5662 ERRelationship erRelation = modelFactory.createERRelation(); 5663 erRelation.addSource(new TableColumnRelationshipElement(tableColumn)); 5664 erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint)); 5665 } 5666 } 5667 } 5668 } 5669 } 5670 } 5671 } 5672 } 5673 else if (option.getIndexCols() != null){ 5674 TPTNodeList<TColumnWithSortOrder> keyNames = option.getIndexCols(); 5675 for (int k = 0; k < keyNames.size(); k++) { 5676 TObjectName keyName = keyNames.getElement(k).getColumnName(); 5677 Table tableModel = modelFactory.createTableByName(stmt.getTableName()); 5678 TableColumn tableConstraint = modelFactory.createTableColumn(tableModel, keyName, true); 5679 if(option.getOptionType() == EAlterTableOptionType.AddConstraintPK){ 5680 tableConstraint.setPrimaryKey(true); 5681 } 5682 else if(option.getOptionType() == EAlterTableOptionType.AddConstraintIndex){ 5683 tableConstraint.setIndexKey(true); 5684 } 5685 else if(option.getOptionType() == EAlterTableOptionType.AddConstraintUnique){ 5686 tableConstraint.setUnqiueKey(true); 5687 } 5688 else if (option.getOptionType() == EAlterTableOptionType.AddConstraintFK) { 5689 TObjectName referencedTableName = option.getReferencedObjectName(); 5690 tableConstraint.setForeignKey(true); 5691 Table referencedTable = modelManager.getTableByName(DlineageUtil.getTableFullName(referencedTableName.toString())); 5692 if (referencedTable == null) { 5693 referencedTable = modelFactory.createTableByName(referencedTableName); 5694 } 5695 TObjectNameList referencedTableColumns = option.getReferencedColumnList(); 5696 if (referencedTableColumns != null) { 5697 for (int j = 0; j < referencedTableColumns.size(); j++) { 5698 TableColumn tableColumn = modelFactory.createTableColumn(referencedTable, 5699 referencedTableColumns.getObjectName(j), false); 5700 if (tableColumn != null) { 5701 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5702 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 5703 relation.setTarget(new TableColumnRelationshipElement(tableConstraint)); 5704 relation.setEffectType(EffectType.foreign_key); 5705 Process process = modelFactory.createProcess(stmt); 5706 relation.setProcess(process); 5707 if(this.option.isShowERDiagram()){ 5708 ERRelationship erRelation = modelFactory.createERRelation(); 5709 erRelation.addSource(new TableColumnRelationshipElement(tableColumn)); 5710 erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint)); 5711 } 5712 } 5713 } 5714 } 5715 else{ 5716 TableColumn tableColumn = modelFactory.createTableColumn(referencedTable, keyName, false); 5717 if (tableColumn != null) { 5718 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5719 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 5720 relation.setTarget(new TableColumnRelationshipElement(tableConstraint)); 5721 relation.setEffectType(EffectType.foreign_key); 5722 Process process = modelFactory.createProcess(stmt); 5723 relation.setProcess(process); 5724 if(this.option.isShowERDiagram()){ 5725 ERRelationship erRelation = modelFactory.createERRelation(); 5726 erRelation.addSource(new TableColumnRelationshipElement(tableColumn)); 5727 erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint)); 5728 } 5729 } 5730 } 5731 } 5732 } 5733 } 5734 } 5735 } 5736 } 5737 5738 private void analyzeAlterViewStmt(TAlterViewStatement stmt) { 5739 if (stmt.getAlterViewOption() == EAlterViewOption.asSelect) { 5740 analyzeCreateViewStmt(stmt, stmt.getSelectSqlStatement(), null, stmt.getViewName()); 5741 } else { 5742 throw new UnsupportedOperationException("Can't handle this alter view statement case, alter option = "+ stmt.getAlterViewOption().name()); 5743 } 5744 } 5745 5746 private void analyzeDeleteStmt(TDeleteSqlStatement stmt) { 5747 TTable table = stmt.getTargetTable(); 5748 if (table == null) 5749 return; 5750 5751 if (table.getCTE() != null) { 5752 table = table.getCTE().getSubquery().getTables().getTable(0); 5753 } else if (table.getLinkTable() != null && table.getLinkTable().getSubquery() != null) { 5754 table = table.getLinkTable().getSubquery().getTables().getTable(0); 5755 } else if (table.getSubquery() != null) { 5756 table = table.getSubquery().getTables().getTable(0); 5757 } 5758 5759 Table tableModel = modelFactory.createTable(table); 5760 if (getTableLinkedColumns(table) != null && getTableLinkedColumns(table).size() > 0) { 5761 for (int j = 0; j < getTableLinkedColumns(table).size(); j++) { 5762 TObjectName object = getTableLinkedColumns(table).getObjectName(j); 5763 5764 if (object.getDbObjectType() == EDbObjectType.variable) { 5765 continue; 5766 } 5767 5768 if (object.getColumnNameOnly().startsWith("@") 5769 && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) { 5770 continue; 5771 } 5772 5773 if (object.getColumnNameOnly().startsWith(":") 5774 && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) { 5775 continue; 5776 } 5777 5778 if (!isBuiltInFunctionName(object)) { 5779 if (object.getSourceTable() == null || object.getSourceTable() == table) { 5780 modelFactory.createTableColumn(tableModel, object, false); 5781 } 5782 } 5783 } 5784 } 5785 5786 if(option.getAnalyzeMode() == AnalyzeMode.crud) { 5787 CrudRelationship crudRelationship = modelFactory.createCrudRelation(); 5788 crudRelationship.setTarget(new TableRelationshipElement(tableModel)); 5789 crudRelationship.setEffectType(EffectType.delete); 5790 } 5791 5792 if (stmt.getWhereClause() != null && stmt.getWhereClause().getCondition() != null) { 5793 analyzeFilterCondition(null, stmt.getWhereClause().getCondition(), null, JoinClauseType.where, 5794 EffectType.delete); 5795 } 5796 } 5797 5798 private TObjectName getProcedureName(TStoredProcedureSqlStatement stmt) { 5799 if (stmt instanceof TTeradataCreateProcedure) { 5800 return ((TTeradataCreateProcedure) stmt).getProcedureName(); 5801 } 5802 return stmt.getStoredProcedureName(); 5803 } 5804 5805 private void analyzePlsqlCreatePackage(TPlsqlCreatePackage stmt) { 5806 TObjectName procedureName = getProcedureName(stmt); 5807 OraclePackage oraclePackage; 5808 if (procedureName != null) { 5809 if (this.modelManager.getOraclePackageByName( 5810 DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getProcedureNameWithArgs(stmt))) == null) { 5811 oraclePackage = this.modelFactory.createOraclePackage(stmt); 5812 5813 if (stmt.getParameterDeclarations() != null) { 5814 TParameterDeclarationList parameters = stmt.getParameterDeclarations(); 5815 5816 for (int i = 0; i < parameters.size(); ++i) { 5817 TParameterDeclaration parameter = parameters.getParameterDeclarationItem(i); 5818 if (parameter.getParameterName() != null) { 5819 this.modelFactory.createProcedureArgument(oraclePackage, parameter, i + 1); 5820 } else if (parameter.getDataType() != null) { 5821 this.modelFactory.createProcedureArgument(oraclePackage, parameter, i + 1); 5822 } 5823 } 5824 } 5825 5826 ModelBindingManager.setGlobalOraclePackage(oraclePackage); 5827 } else { 5828 ModelBindingManager.setGlobalOraclePackage(this.modelManager.getOraclePackageByName( 5829 DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getProcedureNameWithArgs(stmt)))); 5830 } 5831 5832 try { 5833 if (stmt.getDeclareStatements() != null) { 5834 for (int i = 0; i < stmt.getDeclareStatements().size(); ++i) { 5835 analyzeCustomSqlStmt(stmt.getDeclareStatements().get(i)); 5836 } 5837 } 5838 } finally { 5839 ModelBindingManager.removeGlobalOraclePackage(); 5840 } 5841 } 5842 } 5843 5844 private void analyzeStoredProcedureStmt(TStoredProcedureSqlStatement stmt) { 5845 5846 if (stmt instanceof TPlsqlCreatePackage) { 5847 analyzePlsqlCreatePackage((TPlsqlCreatePackage) stmt); 5848 return; 5849 } 5850 5851 ModelBindingManager.setGlobalProcedure(stmt); 5852 5853 try { 5854 Procedure procedure = null; 5855 5856 TObjectName procedureName = getProcedureName(stmt); 5857 5858 // Honor procedure-exclusion patterns/names for procedures defined in actual SQL 5859 // (CREATE PROCEDURE). Previously exclusion was only applied to procedures loaded 5860 // from metadata JSON; a CREATE PROCEDURE parsed from SQL still produced its 5861 // procedure node plus all of its inner-statement processes and relationships 5862 // regardless of the exclusion configuration (MantisBT 4533). 5863 // 5864 // analyzeStoredProcedureStmt also handles functions and triggers (every dialect's 5865 // CREATE FUNCTION / CREATE TRIGGER class extends TStoredProcedureSqlStatement), which 5866 // are NOT procedures and must never be dropped by procedure exclusion. Gate on the 5867 // statement type rather than enumerating classes: across all dialects the procedure 5868 // statement types are exactly those whose ESqlStatementType name contains "procedure" 5869 // (e.g. sstcreateprocedure, sstoraclecreateprocedure, sstmssqlcreateprocedure), 5870 // while function/trigger types contain "function"/"trigger". 5871 boolean isProcedureStmt = stmt.sqlstatementtype != null 5872 && stmt.sqlstatementtype.name().toLowerCase().contains("procedure"); 5873 if (procedureName != null && isProcedureStmt 5874 && DlineageUtil.isProcedureExcluded(procedureName.toString())) { 5875 return; 5876 } 5877 5878 if (procedureName != null) { 5879 procedure = this.modelFactory.createProcedure(stmt); 5880 if (procedure != null) { 5881 modelManager.bindModel(stmt, procedure); 5882 } 5883 if (ModelBindingManager.getGlobalOraclePackage() != null) { 5884 ModelBindingManager.getGlobalOraclePackage().addProcedure(procedure); 5885 procedure.setParentPackage(ModelBindingManager.getGlobalOraclePackage()); 5886 } 5887 if (stmt.getParameterDeclarations() != null) { 5888 TParameterDeclarationList parameters = stmt.getParameterDeclarations(); 5889 5890 for (int i = 0; i < parameters.size(); ++i) { 5891 TParameterDeclaration parameter = parameters.getParameterDeclarationItem(i); 5892 Argument argument = null; 5893 TObjectName argumentName = null; 5894 if (parameter.getParameterName() != null) { 5895 argument = this.modelFactory.createProcedureArgument(procedure, parameter, i + 1); 5896 argumentName = parameter.getParameterName(); 5897 } else if (parameter.getDataType() != null) { 5898 argument = this.modelFactory.createProcedureArgument(procedure, parameter, i + 1); 5899 } 5900 5901 if (argument != null) { 5902 if (argumentName == null) { 5903 argumentName = new TObjectName(); 5904 argumentName.setString(argument.getName()); 5905 } 5906 Variable variable = modelFactory.createVariable(argument.getName()); 5907 if (argument.getMode() == EParameterMode.in || argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) { 5908 variable.setSubType(SubType.of(argument.getMode().name())); 5909 } else { 5910 variable.setSubType(SubType.argument); 5911 } 5912 if(isSimpleDataType(argument.getDataType())){ 5913 modelFactory.createTableColumn(variable, argumentName, true); 5914 } 5915 else { 5916 TObjectName variableProperties = new TObjectName(); 5917 variableProperties.setString("*"); 5918 modelFactory.createTableColumn(variable, variableProperties, true); 5919 } 5920 } 5921 } 5922 } 5923 } 5924 5925 if (stmt instanceof TCreateTriggerStmt) { 5926 TCreateTriggerStmt trigger = (TCreateTriggerStmt) stmt; 5927 5928 if (trigger.getFunctionCall() != null) { 5929 modelFactory.createProcedureFromFunctionCall(trigger.getFunctionCall()); 5930 } 5931 5932 if (trigger.getTables() != null) { 5933 for (int i = 0; i < trigger.getTables().size(); i++) { 5934 Table tableModel = this.modelFactory.createTriggerOnTable(trigger.getTables().getTable(i)); 5935 } 5936 } 5937 } 5938 5939 if (stmt instanceof TPlsqlCreateTrigger 5940 && ((TPlsqlCreateTrigger) stmt).getTriggeringClause().getEventClause() instanceof TDmlEventClause) { 5941 TPlsqlCreateTrigger trigger = (TPlsqlCreateTrigger) stmt; 5942 TDmlEventClause clause = (TDmlEventClause) ((TPlsqlCreateTrigger) stmt).getTriggeringClause() 5943 .getEventClause(); 5944 Table sourceTable = modelFactory.createTableByName(clause.getTableName()); 5945 5946 for (TTriggerEventItem item : clause.getEventItems()) { 5947 if (item instanceof TDmlEventItem) { 5948 if (((TDmlEventItem) item).getColumnList() != null) { 5949 for (TObjectName column : ((TDmlEventItem) item).getColumnList()) { 5950 modelFactory.createTableColumn(sourceTable, column, true); 5951 } 5952 } 5953 } 5954 } 5955 5956 for (TCustomSqlStatement subStmt : ((TPlsqlCreateTrigger) stmt).getStatements()) { 5957 if (!(subStmt instanceof TCommonBlock)) 5958 continue; 5959 for (TCustomSqlStatement blockSubStmt : ((TCommonBlock) subStmt).getStatements()) { 5960 if (!(blockSubStmt instanceof TBasicStmt)) 5961 continue; 5962 TBasicStmt basicStmt = (TBasicStmt) blockSubStmt; 5963 TExpression expression = basicStmt.getExpr(); 5964 if (expression != null && expression.getExpressionType() == EExpressionType.function_t) { 5965 Procedure targetProcedure = modelManager.getProcedureByName(DlineageUtil 5966 .getTableFullName(expression.getFunctionCall().getFunctionName().toString())); 5967 if (targetProcedure == null) { 5968 targetProcedure = modelManager 5969 .getProcedureByName(DlineageUtil.getTableFullName(procedure.getSchema() + "." 5970 + expression.getFunctionCall().getFunctionName().toString())); 5971 } 5972 if (targetProcedure != null && expression.getFunctionCall().getArgs() != null && expression 5973 .getFunctionCall().getArgs().size() == targetProcedure.getArguments().size()) { 5974 for (int j = 0; j < expression.getFunctionCall().getArgs().size(); j++) { 5975 TExpression columnExpr = expression.getFunctionCall().getArgs().getExpression(j); 5976 if (columnExpr.getExpressionType() == EExpressionType.simple_object_name_t) { 5977 TObjectName columnObject = columnExpr.getObjectOperand(); 5978 if (columnObject.toString().indexOf(":") != -1) { 5979 TableColumn tableColumn = modelFactory.createTableColumn(sourceTable, 5980 columnObject, true); 5981 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 5982 relation.setEffectType(EffectType.trigger); 5983 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 5984 relation.setTarget( 5985 new ArgumentRelationshipElement(targetProcedure.getArguments().get(j))); 5986 Process process = modelFactory.createProcess(stmt); 5987 relation.setProcess(process); 5988 } 5989 } 5990 } 5991 } 5992 } 5993 } 5994 } 5995 } 5996 5997 if (stmt instanceof TMssqlCreateFunction) { 5998 TMssqlCreateFunction createFunction = (TMssqlCreateFunction) stmt; 5999 if (createFunction.getReturnTableVaraible() != null && createFunction.getReturnTableDefinitions() != null) { 6000 Variable tableModel = this.modelFactory.createVariable(createFunction.getReturnTableVaraible()); 6001 tableModel.setVariable(true); 6002 tableModel.setCreateTable(true); 6003 String procedureParent = createFunction.getFunctionName().toString(); 6004 if (procedureParent != null) { 6005 tableModel.setParent(procedureParent); 6006 } 6007 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), tableModel); 6008 6009 if (createFunction.getReturnTableDefinitions() != null) { 6010 for (int j = 0; j < createFunction.getReturnTableDefinitions().size(); j++) { 6011 TTableElement tableElement = createFunction.getReturnTableDefinitions().getTableElement(j); 6012 TColumnDefinition column = tableElement.getColumnDefinition(); 6013 if (column != null && column.getColumnName() != null) { 6014 modelFactory.createTableColumn(tableModel, column.getColumnName(), true); 6015 } 6016 } 6017 } 6018 } 6019 6020 if (createFunction.getReturnStmt() != null && createFunction.getReturnStmt().getSubquery() != null) { 6021 String procedureParent = createFunction.getFunctionName().toString(); 6022 analyzeSelectStmt(createFunction.getReturnStmt().getSubquery()); 6023 ResultSet resultSetModel = (ResultSet) modelManager 6024 .getModel(createFunction.getReturnStmt().getSubquery()); 6025 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), 6026 resultSetModel); 6027 } 6028 } else if (stmt instanceof TCreateFunctionStmt) { 6029 TCreateFunctionStmt createFunction = (TCreateFunctionStmt) stmt; 6030 if (createFunction.getReturnDataType() != null 6031 && createFunction.getReturnDataType().getColumnDefList() != null) { 6032 Table tableModel = this.modelFactory.createTableByName(createFunction.getFunctionName(), true); 6033 tableModel.setCreateTable(true); 6034 String procedureParent = createFunction.getFunctionName().toString(); 6035 if (procedureParent != null) { 6036 tableModel.setParent(procedureParent); 6037 } 6038 6039 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), tableModel); 6040 for (int j = 0; j < createFunction.getReturnDataType().getColumnDefList().size(); j++) { 6041 TColumnDefinition column = createFunction.getReturnDataType().getColumnDefList().getColumn(j); 6042 if (column != null && column.getColumnName() != null) { 6043 modelFactory.createTableColumn(tableModel, column.getColumnName(), true); 6044 } 6045 } 6046 6047 if (createFunction.getSqlQuery() != null) { 6048 analyzeSelectStmt(createFunction.getSqlQuery()); 6049 ResultSet resultSetModel = (ResultSet) modelManager.getModel(createFunction.getSqlQuery()); 6050 if (resultSetModel != null) { 6051 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 6052 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 6053 for (int j = 0; j < tableModel.getColumns().size(); j++) { 6054 TableColumn tableColumn = tableModel.getColumns().get(j); 6055 if (DlineageUtil.compareColumnIdentifier(getColumnName(resultColumn.getName()), 6056 DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 6057 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 6058 dataflowRelation.setEffectType(EffectType.select); 6059 dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn)); 6060 dataflowRelation.setTarget(new TableColumnRelationshipElement(tableColumn)); 6061 } 6062 } 6063 } 6064 } 6065 } 6066 } 6067 6068 if (createFunction.getReturnStmt() != null && createFunction.getReturnStmt().getSubquery() != null) { 6069 String procedureParent = createFunction.getFunctionName().toString(); 6070 analyzeSelectStmt(createFunction.getReturnStmt().getSubquery()); 6071 ResultSet resultSetModel = (ResultSet) modelManager 6072 .getModel(createFunction.getReturnStmt().getSubquery()); 6073 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), 6074 resultSetModel); 6075 } 6076 6077 if (createFunction.getReturnStmt() != null && createFunction.getReturnStmt().getReturnExpr() != null) { 6078 TExpression returnExpression = createFunction.getReturnStmt().getReturnExpr(); 6079 ResultSet returnResult = modelFactory.createResultSet(createFunction.getReturnStmt(), false); 6080 ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, returnExpression); 6081 6082 TExpression expression = createFunction.getReturnStmt().getReturnExpr(); 6083 analyzeResultColumnExpressionRelation(resultColumn, expression); 6084 6085 String procedureParent = createFunction.getFunctionName().toString(); 6086 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), 6087 returnResult); 6088 } 6089 } 6090 6091 if (stmt instanceof TCreateProcedureStmt) { 6092 TCreateProcedureStmt createProcedure = (TCreateProcedureStmt) stmt; 6093 if (EDbVendor.dbvsnowflake == option.getVendor() && createProcedure.getRoutineBodyInConstant() != null) { 6094 extractSnowflakeSQLFromProcedure(createProcedure); 6095 } 6096 } 6097 6098 if (stmt.getStatements().size() > 0) { 6099 for (int i = 0; i < stmt.getStatements().size(); ++i) { 6100 this.analyzeCustomSqlStmt(stmt.getStatements().get(i)); 6101 } 6102 } 6103 6104 if (stmt.getBodyStatements().size() > 0) { 6105 for (int i = 0; i < stmt.getBodyStatements().size(); ++i) { 6106 this.analyzeCustomSqlStmt(stmt.getBodyStatements().get(i)); 6107 } 6108 } 6109 6110 // Detect pipelined functions and build signatures 6111 if (stmt instanceof TPlsqlCreateFunction && pipelinedAnalyzer != null) { 6112 try { 6113 pipelinedAnalyzer.analyzePipelinedFunction((TPlsqlCreateFunction) stmt); 6114 } catch (Exception e) { 6115 // Don't let pipelined analysis failure break main flow 6116 } 6117 } 6118 6119 if (procedure != null && !getLastSelectStmt(stmt).isEmpty()) { 6120 for (TSelectSqlStatement select : getLastSelectStmt(stmt)) { 6121 ResultSet resultSet = (ResultSet) modelManager.getModel(select); 6122 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedure.getName()), 6123 resultSet); 6124 } 6125// List<Argument> outArgs = new ArrayList<Argument>(); 6126// for (int i = 0; i < procedure.getArguments().size(); i++) { 6127// Argument argument = procedure.getArguments().get(i); 6128// if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) { 6129// outArgs.add(argument); 6130// } 6131// } 6132// 6133// if (resultSet != null && resultSet.getColumns().size() == outArgs.size()) { 6134// for (int i = 0; i < outArgs.size(); i++) { 6135// Argument argument = outArgs.get(i); 6136// Variable variable = modelFactory.createVariable(argument.getName(), false); 6137// if (variable != null) { 6138// DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 6139// dataflowRelation.setEffectType(EffectType.output); 6140// dataflowRelation 6141// .addSource(new ResultColumnRelationshipElement(resultSet.getColumns().get(i))); 6142// dataflowRelation 6143// .setTarget(new TableColumnRelationshipElement(variable.getColumns().get(0))); 6144// } 6145// } 6146// 6147// } 6148 } 6149 6150 if (stmt instanceof TCreateFunctionStmt && ((TCreateFunctionStmt)stmt).getSqlExpression()!=null) { 6151 TCreateFunctionStmt createFunction = (TCreateFunctionStmt) stmt; 6152 TExpression returnExpression = createFunction.getSqlExpression(); 6153 6154 ResultSet returnResult = modelFactory.createResultSet(stmt, false); 6155 ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, returnExpression); 6156 6157 columnsInExpr visitor = new columnsInExpr(); 6158 returnExpression.inOrderTraverse(visitor); 6159 6160 List<TObjectName> objectNames = visitor.getObjectNames(); 6161 List<TParseTreeNode> functions = visitor.getFunctions(); 6162 List<TParseTreeNode> constants = visitor.getConstants(); 6163 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 6164 6165 if (functions != null && !functions.isEmpty()) { 6166 analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function); 6167 } 6168 if (subquerys != null && !subquerys.isEmpty()) { 6169 analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select); 6170 } 6171 if (objectNames != null && !objectNames.isEmpty()) { 6172 analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions); 6173 } 6174 if (constants != null && !constants.isEmpty()) { 6175 analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions); 6176 } 6177 6178 String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt)); 6179 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), 6180 returnResult); 6181 } 6182 } finally { 6183 ModelBindingManager.removeGlobalProcedure(); 6184 } 6185 6186 } 6187 6188 private boolean isSimpleDataType(TTypeName dataType) { 6189 if (dataType.getDataType() == EDataType.variant_t) { 6190 return false; 6191 } 6192 if (dataType.getDataType() == EDataType.cursor_t) { 6193 return false; 6194 } 6195 if (dataType.getDataType() == EDataType.generic_t) { 6196 return false; 6197 } 6198 if (dataType.getDataType() == EDataType.unknown_t) { 6199 return false; 6200 } 6201 if (dataType.getDataType() == EDataType.sql_variant_t) { 6202 return false; 6203 } 6204 if (dataType.getDataType() == EDataType.table_t) { 6205 return false; 6206 } 6207 if (dataType.getDataType() == EDataType.raw_t) { 6208 return false; 6209 } 6210 if (dataType.getDataType() == EDataType.resultset_t) { 6211 return false; 6212 } 6213 if (dataType.getDataType() == EDataType.row_t) { 6214 return false; 6215 } 6216 if (dataType.getDataType() == EDataType.map_t) { 6217 return false; 6218 } 6219 if (dataType.getDataType() == EDataType.anyType_t) { 6220 return false; 6221 } 6222 if (dataType.getDataType() == EDataType.struct_t) { 6223 return false; 6224 } 6225 if (dataType.getDataType() == EDataType.structType_t) { 6226 return false; 6227 } 6228 if (dataType.getDataType() == EDataType.mapType_t) { 6229 return false; 6230 } 6231 return true; 6232 } 6233 6234 protected void analyzeResultColumnExpressionRelation(Object resultColumn, TExpression expression) { 6235 columnsInExpr visitor = new columnsInExpr(); 6236 expression.inOrderTraverse(visitor); 6237 List<TObjectName> objectNames = visitor.getObjectNames(); 6238 List<TParseTreeNode> functions = visitor.getFunctions(); 6239 List<TParseTreeNode> constants = visitor.getConstants(); 6240 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 6241 6242 if (functions != null && !functions.isEmpty()) { 6243 analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function); 6244 } 6245 if (subquerys != null && !subquerys.isEmpty()) { 6246 analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select); 6247 } 6248 if (objectNames != null && !objectNames.isEmpty()) { 6249 analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions); 6250 } 6251 if (constants != null && !constants.isEmpty()) { 6252 analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions); 6253 } 6254 } 6255 6256 private void analyzeDb2ReturnStmt(TDb2ReturnStmt stmt) { 6257 if (stmt.getReturnExpr() != null) { 6258 TExpression returnExpression = stmt.getReturnExpr(); 6259 ResultSet returnResult = modelFactory.createResultSet(stmt, true); 6260 ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, returnExpression); 6261 6262 columnsInExpr visitor = new columnsInExpr(); 6263 stmt.getReturnExpr().inOrderTraverse(visitor); 6264 6265 List<TObjectName> objectNames = visitor.getObjectNames(); 6266 List<TParseTreeNode> functions = visitor.getFunctions(); 6267 List<TParseTreeNode> constants = visitor.getConstants(); 6268 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 6269 6270 if (functions != null && !functions.isEmpty()) { 6271 analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function); 6272 } 6273 if (subquerys != null && !subquerys.isEmpty()) { 6274 analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select); 6275 } 6276 if (objectNames != null && !objectNames.isEmpty()) { 6277 analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions); 6278 } 6279 if (constants != null && !constants.isEmpty()) { 6280 analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions); 6281 } 6282 6283 String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt)); 6284 if (procedureParent != null) { 6285 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), 6286 returnResult); 6287 } 6288 } 6289 } 6290 6291 private void analyzeReturnStmt(TReturnStmt stmt) { 6292 if (stmt.getResultColumnList() != null) { 6293 ResultSet returnResult = modelFactory.createResultSet(stmt, true); 6294 for (TResultColumn column : stmt.getResultColumnList()) { 6295 ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, column); 6296 6297 columnsInExpr visitor = new columnsInExpr(); 6298 column.getExpr().inOrderTraverse(visitor); 6299 6300 List<TObjectName> objectNames = visitor.getObjectNames(); 6301 List<TParseTreeNode> functions = visitor.getFunctions(); 6302 List<TParseTreeNode> constants = visitor.getConstants(); 6303 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 6304 6305 if (functions != null && !functions.isEmpty()) { 6306 analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function); 6307 } 6308 if (subquerys != null && !subquerys.isEmpty()) { 6309 analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select); 6310 } 6311 if (objectNames != null && !objectNames.isEmpty()) { 6312 analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions); 6313 } 6314 if (constants != null && !constants.isEmpty()) { 6315 analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions); 6316 } 6317 6318 } 6319 6320 String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt)); 6321 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), 6322 returnResult); 6323 } 6324 else if(stmt.getExpression()!=null){ 6325 TExpression returnExpression = stmt.getExpression(); 6326 ResultSet returnResult = modelFactory.createResultSet(stmt, true); 6327 6328 columnsInExpr visitor = null; 6329 List<TSelectSqlStatement> subquerys = null; 6330 6331 if (returnExpression.getFunctionCall() != null 6332 && returnExpression.getFunctionCall().getFunctionName().toString().equalsIgnoreCase("table") 6333 && returnExpression.getFunctionCall().getArgs() != null 6334 && returnExpression.getFunctionCall().getArgs().size()>0) { 6335 visitor = new columnsInExpr(); 6336 returnExpression.getFunctionCall().getArgs().getExpression(0).inOrderTraverse(visitor); 6337 subquerys = visitor.getSubquerys(); 6338 if (subquerys != null && !subquerys.isEmpty()) { 6339 analyzeSelectStmt(subquerys.get(0)); 6340 ResultSet resultSet = (ResultSet) modelManager.getModel(subquerys.get(0)); 6341 if (resultSet != null && resultSet.getColumns() != null) { 6342 for (ResultColumn column : resultSet.getColumns()) { 6343 TObjectName columnName = new TObjectName(); 6344 columnName.setString(column.getName()); 6345 ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, columnName); 6346 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 6347 dataflowRelation.setEffectType(EffectType.select); 6348 dataflowRelation.addSource(new ResultColumnRelationshipElement(column)); 6349 dataflowRelation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 6350 } 6351 } 6352 returnResult.setDetermined(resultSet.isDetermined()); 6353 String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt)); 6354 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), 6355 returnResult); 6356 return; 6357 } 6358 } 6359 6360 ResultColumn resultColumn = null; 6361 if (returnExpression.getExpressionType() == EExpressionType.simple_object_name_t) { 6362 TObjectName columnName = new TObjectName(); 6363 columnName.setString("*"); 6364 resultColumn = modelFactory.createResultColumn(returnResult, columnName); 6365 } 6366 else { 6367 resultColumn = modelFactory.createResultColumn(returnResult, returnExpression); 6368 } 6369 6370 visitor = new columnsInExpr(); 6371 stmt.getExpression().inOrderTraverse(visitor); 6372 6373 List<TObjectName> objectNames = visitor.getObjectNames(); 6374 List<TParseTreeNode> functions = visitor.getFunctions(); 6375 List<TParseTreeNode> constants = visitor.getConstants(); 6376 subquerys = visitor.getSubquerys(); 6377 6378 if (functions != null && !functions.isEmpty()) { 6379 analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function); 6380 } 6381 if (subquerys != null && !subquerys.isEmpty()) { 6382 analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select); 6383 } 6384 if (objectNames != null && !objectNames.isEmpty()) { 6385 DataFlowRelationship relation = analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions); 6386 //如果variable对应的不是一个复杂结构,则resultColumn不要设置为* 6387 if (relation != null && relation.getTarget().getElement() == resultColumn && relation.getSources().size() == 1) { 6388 Object column = relation.getSources().iterator().next().getElement(); 6389 boolean star = true; 6390 if (column instanceof TableColumn && ((TableColumn) column).getName().indexOf("*") == -1) { 6391 star = false; 6392 } 6393 if (column instanceof ResultColumn && ((ResultColumn) column).getName().indexOf("*") == -1) { 6394 star = false; 6395 } 6396 if (!star && returnExpression.getExpressionType() == EExpressionType.simple_object_name_t) { 6397 resultColumn = modelFactory.createResultColumn(returnResult, returnExpression.getObjectOperand()); 6398 returnResult.getColumns().clear(); 6399 returnResult.addColumn(resultColumn); 6400 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 6401 } 6402 } 6403 } 6404 if (constants != null && !constants.isEmpty()) { 6405 analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions); 6406 } 6407 6408 String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt)); 6409 if (procedureParent != null) { 6410 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), 6411 returnResult); 6412 } 6413 } 6414 } 6415 6416 private void analyzeMssqlReturnStmt(TMssqlReturn stmt) { 6417 if (stmt.getResultColumnList() != null) { 6418 ResultSet returnResult = modelFactory.createResultSet(stmt, true); 6419 for (TResultColumn column : stmt.getResultColumnList()) { 6420 ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, column); 6421 6422 columnsInExpr visitor = new columnsInExpr(); 6423 column.getExpr().inOrderTraverse(visitor); 6424 6425 List<TObjectName> objectNames = visitor.getObjectNames(); 6426 List<TParseTreeNode> functions = visitor.getFunctions(); 6427 List<TParseTreeNode> constants = visitor.getConstants(); 6428 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 6429 6430 if (functions != null && !functions.isEmpty()) { 6431 analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function); 6432 } 6433 if (subquerys != null && !subquerys.isEmpty()) { 6434 analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select); 6435 } 6436 if (objectNames != null && !objectNames.isEmpty()) { 6437 analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions); 6438 } 6439 if (constants != null && !constants.isEmpty()) { 6440 analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions); 6441 } 6442 6443 } 6444 6445 String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt)); 6446 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), 6447 returnResult); 6448 } 6449 else if(stmt.getReturnExpr()!=null){ 6450 TExpression returnExpression = stmt.getReturnExpr(); 6451 ResultSet returnResult = modelFactory.createResultSet(stmt, true); 6452 6453 if (returnExpression.getSubQuery() == null) { 6454 ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, returnExpression); 6455 columnsInExpr visitor = new columnsInExpr(); 6456 stmt.getReturnExpr().inOrderTraverse(visitor); 6457 6458 List<TObjectName> objectNames = visitor.getObjectNames(); 6459 List<TParseTreeNode> functions = visitor.getFunctions(); 6460 List<TParseTreeNode> constants = visitor.getConstants(); 6461 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 6462 6463 if (functions != null && !functions.isEmpty()) { 6464 analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function); 6465 } 6466 if (subquerys != null && !subquerys.isEmpty()) { 6467 analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select); 6468 } 6469 if (objectNames != null && !objectNames.isEmpty()) { 6470 analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions); 6471 } 6472 if (constants != null && !constants.isEmpty()) { 6473 analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions); 6474 } 6475 } 6476 else { 6477 analyzeSelectStmt(returnExpression.getSubQuery()); 6478 ResultSet subResultSet = (ResultSet)modelManager.getModel(returnExpression.getSubQuery()); 6479 if (subResultSet != null) { 6480 for (ResultColumn subResultColumn : subResultSet.getColumns()) { 6481 TObjectName objectName = new TObjectName(); 6482 objectName.setString(subResultColumn.getName()); 6483 ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, objectName); 6484 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 6485 dataflowRelation.setEffectType(EffectType.select); 6486 dataflowRelation.addSource(new ResultColumnRelationshipElement(subResultColumn)); 6487 dataflowRelation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 6488 6489 } 6490 6491 if(subResultSet.getRelationRows().hasRelation()) { 6492 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 6493 impactRelation.setEffectType(EffectType.select); 6494 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 6495 subResultSet.getRelationRows())); 6496 impactRelation.setTarget( 6497 new RelationRowsRelationshipElement<ResultSetRelationRows>(returnResult.getRelationRows())); 6498 } 6499 } 6500 } 6501 6502 String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt)); 6503 if (procedureParent != null) { 6504 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), 6505 returnResult); 6506 } 6507 } 6508 } 6509 6510 private void analyzeFetchStmt(TFetchStmt stmt) { 6511 if (stmt.getVariableNames() != null) { 6512 for (int i = 0; i < stmt.getVariableNames().size(); i++) { 6513 TExpression variableExpression = stmt.getVariableNames().getExpression(i); 6514 if (variableExpression.getExpressionType() == EExpressionType.simple_object_name_t) { 6515 TObjectName columnObject = variableExpression.getObjectOperand(); 6516 if (columnObject.getDbObjectType() == EDbObjectType.variable) { 6517 continue; 6518 } 6519 6520 if (columnObject.getColumnNameOnly().startsWith("@") && (option.getVendor() == EDbVendor.dbvmssql 6521 || option.getVendor() == EDbVendor.dbvazuresql)) { 6522 continue; 6523 } 6524 6525 if (columnObject.getColumnNameOnly().startsWith(":") && (option.getVendor() == EDbVendor.dbvhana 6526 || option.getVendor() == EDbVendor.dbvteradata)) { 6527 continue; 6528 } 6529 6530 Variable cursorVariable = modelFactory.createVariable(columnObject); 6531 cursorVariable.setSubType(SubType.record); 6532 if (cursorVariable.isDetermined()) { 6533 if (stmt.getCursorName() != null) { 6534 String procedureName = DlineageUtil.getProcedureParentName(stmt); 6535 String variableString = stmt.getCursorName().toString(); 6536 if (variableString.startsWith(":")) { 6537 variableString = variableString.substring(variableString.indexOf(":") + 1); 6538 } 6539 if (!SQLUtil.isEmpty(procedureName)) { 6540 variableString = procedureName + "." 6541 + SQLUtil.getIdentifierNormalTableName(variableString); 6542 } 6543 Table cursor = modelManager.getTableByName(DlineageUtil.getTableFullName(variableString)); 6544 if (cursor != null) { 6545 for (TableColumn variableProperty : cursorVariable.getColumns()) { 6546 boolean flag = false; 6547 for (TableColumn cursorColumn : cursor.getColumns()) { 6548 if (getColumnName(cursorColumn.getName()) 6549 .equalsIgnoreCase(variableProperty.getName())) { 6550 DataFlowRelationship dataflowRelation = modelFactory 6551 .createDataFlowRelation(); 6552 dataflowRelation.setEffectType(EffectType.cursor); 6553 dataflowRelation 6554 .addSource(new TableColumnRelationshipElement(cursorColumn)); 6555 dataflowRelation 6556 .setTarget(new TableColumnRelationshipElement(variableProperty)); 6557 flag = true; 6558 break; 6559 } 6560 } 6561 6562 if (!flag) { 6563 if (cursor.getColumns().size() == stmt.getVariableNames().size()) { 6564 DataFlowRelationship dataflowRelation = modelFactory 6565 .createDataFlowRelation(); 6566 dataflowRelation.setEffectType(EffectType.cursor); 6567 dataflowRelation 6568 .setTarget(new TableColumnRelationshipElement(variableProperty)); 6569 dataflowRelation.addSource( 6570 new TableColumnRelationshipElement(cursor.getColumns().get(i))); 6571 } 6572 else { 6573 for (int j = 0; j < cursor.getColumns().size(); j++) { 6574 DataFlowRelationship dataflowRelation = modelFactory 6575 .createDataFlowRelation(); 6576 dataflowRelation.setEffectType(EffectType.cursor); 6577 if (stmt.getVariableNames().size() == 1) { 6578 dataflowRelation.addSource(new TableColumnRelationshipElement( 6579 cursor.getColumns().get(j))); 6580 } else { 6581 dataflowRelation.addSource(new TableColumnRelationshipElement( 6582 cursor.getColumns().get(j), i)); 6583 } 6584 dataflowRelation.setTarget( 6585 new TableColumnRelationshipElement(variableProperty)); 6586 } 6587 } 6588 } 6589 } 6590 } 6591 } 6592 6593 } else { 6594 TableColumn variableProperty = null; 6595 if (stmt.getVariableNames().size() == 1) { 6596 if (cursorVariable.getColumns() == null || cursorVariable.getColumns().isEmpty()) { 6597 TObjectName starColumn = new TObjectName(); 6598 starColumn.setString("*"); 6599 variableProperty = modelFactory.createTableColumn(cursorVariable, starColumn, true); 6600 } else { 6601 variableProperty = cursorVariable.getColumns().get(0); 6602 } 6603 } else { 6604 variableProperty = modelFactory.createTableColumn(cursorVariable, columnObject, true); 6605 } 6606 6607 if (stmt.getCursorName() != null) { 6608 String procedureName = DlineageUtil.getProcedureParentName(stmt); 6609 String variableString = stmt.getCursorName().toString(); 6610 if (variableString.startsWith(":")) { 6611 variableString = variableString.substring(variableString.indexOf(":") + 1); 6612 } 6613 if (!SQLUtil.isEmpty(procedureName)) { 6614 variableString = procedureName + "." 6615 + SQLUtil.getIdentifierNormalTableName(variableString); 6616 } 6617 Table cursor = modelManager.getTableByName(DlineageUtil.getTableFullName(variableString)); 6618 if (cursor != null) { 6619 for (int j = 0; j < cursor.getColumns().size(); j++) { 6620 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 6621 dataflowRelation.setEffectType(EffectType.cursor); 6622 if (stmt.getVariableNames().size() == 1) { 6623 dataflowRelation.addSource( 6624 new TableColumnRelationshipElement(cursor.getColumns().get(j))); 6625 } else { 6626 dataflowRelation.addSource( 6627 new TableColumnRelationshipElement(cursor.getColumns().get(j), i)); 6628 } 6629 dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty)); 6630 } 6631 } 6632 } 6633 } 6634 } 6635 } 6636 } 6637 } 6638 6639 private void analyzeFetchStmt(TMssqlFetch stmt) { 6640 if (stmt.getVariableNames() != null) { 6641 for (int i = 0; i < stmt.getVariableNames().size(); i++) { 6642 TObjectName columnObject = stmt.getVariableNames().getObjectName(i); 6643 Variable cursorVariable = modelFactory.createVariable(columnObject); 6644 cursorVariable.setCreateTable(true); 6645 cursorVariable.setSubType(SubType.record); 6646 TableColumn variableProperty = null; 6647 if (stmt.getVariableNames().size() == 1) { 6648 if (cursorVariable.getColumns() == null || cursorVariable.getColumns().isEmpty()) { 6649 TObjectName starColumn = new TObjectName(); 6650 starColumn.setString("*"); 6651 variableProperty = modelFactory.createTableColumn(cursorVariable, starColumn, true); 6652 } else { 6653 variableProperty = cursorVariable.getColumns().get(0); 6654 } 6655 } else { 6656 variableProperty = modelFactory.createTableColumn(cursorVariable, columnObject, true); 6657 } 6658 6659 if (stmt.getCursorName() != null) { 6660 String procedureName = DlineageUtil.getProcedureParentName(stmt); 6661 String variableString = stmt.getCursorName().toString(); 6662 if (variableString.startsWith(":")) { 6663 variableString = variableString.substring(variableString.indexOf(":") + 1); 6664 } 6665 if (!SQLUtil.isEmpty(procedureName)) { 6666 variableString = procedureName + "." + SQLUtil.getIdentifierNormalTableName(variableString); 6667 } 6668 Table cursor = modelManager 6669 .getTableByName(DlineageUtil.getTableFullName(variableString)); 6670 if (cursor != null) { 6671 for (int j = 0; j < cursor.getColumns().size(); j++) { 6672 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 6673 dataflowRelation.setEffectType(EffectType.cursor); 6674 if (stmt.getVariableNames().size() == 1) { 6675 dataflowRelation 6676 .addSource(new TableColumnRelationshipElement(cursor.getColumns().get(j))); 6677 } else { 6678 dataflowRelation 6679 .addSource(new TableColumnRelationshipElement(cursor.getColumns().get(j), i)); 6680 } 6681 dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty)); 6682 } 6683 } 6684 } 6685 } 6686 6687 } 6688 } 6689 6690 private void analyzeLoopStmt(TLoopStmt stmt) { 6691 6692 if (stmt.getCursorName() != null && stmt.getIndexName() != null) { 6693 modelManager.bindCursorIndex(stmt.getIndexName(), stmt.getCursorName()); 6694 } 6695 6696 if (stmt.getRecordName() != null && stmt.getSubquery() != null) { 6697 Variable cursorTempTable = modelFactory.createCursor(stmt); 6698 cursorTempTable.setVariable(true); 6699 cursorTempTable.setSubType(SubType.cursor); 6700 modelManager.bindCursorModel(stmt, cursorTempTable); 6701 analyzeSelectStmt(stmt.getSubquery()); 6702 6703 TableColumn cursorColumn = null; 6704 if (cursorTempTable.getColumns() == null || cursorTempTable.getColumns().isEmpty()) { 6705 TObjectName starColumn = new TObjectName(); 6706 starColumn.setString("*"); 6707 cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true); 6708 } else { 6709 cursorColumn = cursorTempTable.getColumns().get(0); 6710 } 6711 6712 6713 ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubquery()); 6714 if (resultSetModel != null) { 6715 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 6716 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 6717 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 6718 dataflowRelation.setEffectType(EffectType.cursor); 6719 dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn)); 6720 dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn)); 6721 } 6722 } 6723 } 6724 6725 for (int i = 0; i < stmt.getStatements().size(); i++) { 6726 analyzeCustomSqlStmt(stmt.getStatements().get(i)); 6727 } 6728 } 6729 6730 private void analyzeForStmt(TForStmt stmt) { 6731 if (stmt.getSubquery() == null) { 6732 return; 6733 } 6734 6735 Variable cursorTempTable = modelFactory.createCursor(stmt); 6736 cursorTempTable.setVariable(true); 6737 cursorTempTable.setSubType(SubType.cursor); 6738 cursorTempTable.setCreateTable(true); 6739 modelManager.bindCursorModel(stmt, cursorTempTable); 6740 analyzeSelectStmt(stmt.getSubquery()); 6741 6742 TableColumn cursorColumn = null; 6743 if (cursorTempTable.getColumns() == null || cursorTempTable.getColumns().isEmpty()) { 6744 TObjectName starColumn = new TObjectName(); 6745 starColumn.setString("*"); 6746 cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true); 6747 } else { 6748 cursorColumn = cursorTempTable.getColumns().get(0); 6749 } 6750 6751 6752 ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubquery()); 6753 if (resultSetModel != null) { 6754 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 6755 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 6756 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 6757 dataflowRelation.setEffectType(EffectType.cursor); 6758 dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn)); 6759 dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn)); 6760 } 6761 } 6762 6763 if (stmt.getStatements() != null && stmt.getStatements().size() > 0) { 6764 for (int i = 0; i < stmt.getStatements().size(); i++) { 6765 analyzeCustomSqlStmt(stmt.getStatements().get(i)); 6766 } 6767 } 6768 } 6769 6770 private void analyzeVarDeclStmt(TVarDeclStmt stmt) { 6771 TTypeName typeName = stmt.getDataType(); 6772 if (typeName != null && typeName.toString().toUpperCase().indexOf("ROWTYPE") != -1) { 6773 Variable cursorVariable = modelFactory.createVariable(stmt.getElementName()); 6774 cursorVariable.setSubType(SubType.record_type); 6775 6776 Table variableTable = modelFactory.createTableByName(typeName.getDataTypeName(), false); 6777 if(!variableTable.isCreateTable()) { 6778 TObjectName starColumn1 = new TObjectName(); 6779 starColumn1.setString("*"); 6780 TableColumn variableTableStarColumn = modelFactory.createTableColumn(variableTable, starColumn1, true); 6781 variableTableStarColumn.setShowStar(false); 6782 variableTableStarColumn.setExpandStar(true); 6783 6784 TObjectName starColumn = new TObjectName(); 6785 starColumn.setString("*"); 6786 TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable, starColumn, true); 6787 variableProperty.setShowStar(false); 6788 variableProperty.setExpandStar(true); 6789 6790 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 6791 dataflowRelation.setEffectType(EffectType.rowtype); 6792 dataflowRelation.addSource(new TableColumnRelationshipElement(variableTableStarColumn)); 6793 dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty)); 6794 } else { 6795 for (TableColumn sourceColumn : variableTable.getColumns()) { 6796 String columnName = sourceColumn.getName(); 6797 TObjectName targetColumn = new TObjectName(); 6798 targetColumn.setString(columnName); 6799 TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable, targetColumn, true); 6800 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 6801 dataflowRelation.setEffectType(EffectType.rowtype); 6802 dataflowRelation.addSource(new TableColumnRelationshipElement(sourceColumn)); 6803 dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty)); 6804 } 6805 } 6806 } else if (stmt.getElementName() != null) { 6807 Variable variable = modelFactory.createVariable(stmt.getElementName()); 6808 variable.setCreateTable(true); 6809 variable.setSubType(SubType.record); 6810 TableColumn tableColumn = null; 6811 if (stmt.getDataType() != null && (modelFactory.createVariable(stmt.getDataType().getDataTypeName(), false)!=null || isCursorType(stmt.getDataType().getDataTypeName()))) { 6812 Variable cursorVariable = modelFactory.createVariable(stmt.getDataType().getDataTypeName(), false); 6813 if (cursorVariable != null) { 6814 if (cursorVariable.getSubType() == SubType.record_type) { 6815 variable.setSubType(SubType.record_type); 6816 } 6817 if(cursorVariable.isDetermined()) { 6818 for (int k = 0; k < cursorVariable.getColumns().size(); k++) { 6819 TableColumn sourceColumn = cursorVariable.getColumns().get(k); 6820 TObjectName objectName = new TObjectName(); 6821 objectName.setString(sourceColumn.getName()); 6822 tableColumn = modelFactory.createTableColumn(variable, objectName, true); 6823 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 6824 dataflowRelation.setEffectType(EffectType.cursor); 6825 dataflowRelation 6826 .addSource(new TableColumnRelationshipElement(sourceColumn)); 6827 dataflowRelation.setTarget(new TableColumnRelationshipElement(tableColumn)); 6828 } 6829 variable.setDetermined(true); 6830 return; 6831 } 6832 else { 6833 TObjectName objectName = new TObjectName(); 6834 objectName.setString("*"); 6835 tableColumn = modelFactory.createTableColumn(variable, objectName, true); 6836 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 6837 dataflowRelation.setEffectType(EffectType.cursor); 6838 dataflowRelation 6839 .addSource(new TableColumnRelationshipElement(cursorVariable.getColumns().get(0))); 6840 dataflowRelation.setTarget(new TableColumnRelationshipElement(tableColumn)); 6841 } 6842 } 6843 else { 6844 TObjectName objectName = new TObjectName(); 6845 objectName.setString("*"); 6846 tableColumn = modelFactory.createTableColumn(variable, objectName, true); 6847 } 6848 } else { 6849 tableColumn = modelFactory.createTableColumn(variable, stmt.getElementName(), true); 6850 tableColumn.setVariant(true); 6851 } 6852 6853 if (stmt.getDefaultValue() != null) { 6854 columnsInExpr visitor = new columnsInExpr(); 6855 stmt.getDefaultValue().inOrderTraverse(visitor); 6856 List<TObjectName> objectNames = visitor.getObjectNames(); 6857 List<TParseTreeNode> functions = visitor.getFunctions(); 6858 List<TParseTreeNode> constants = visitor.getConstants(); 6859 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 6860 6861 if (functions != null && !functions.isEmpty()) { 6862 analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function); 6863 } 6864 if (subquerys != null && !subquerys.isEmpty()) { 6865 analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select); 6866 } 6867 if (objectNames != null && !objectNames.isEmpty()) { 6868 analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions); 6869 } 6870 if (constants != null && !constants.isEmpty()) { 6871 analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, functions); 6872 } 6873 } 6874 6875 6876 } 6877 } 6878 6879 private boolean isCursorType(String dataTypeName) { 6880 if (dataTypeName != null && dataTypeName.toLowerCase().contains("cursor")) { 6881 return true; 6882 } 6883 return false; 6884 } 6885 6886 private void analyzeSetStmt(TSetStmt stmt) { 6887 TExpression right = stmt.getVariableValue(); 6888 TObjectName columnObject = stmt.getVariableName(); 6889 if (columnObject != null) { 6890 TableColumn tableColumn = null; 6891 Variable tableModel; 6892 if (columnObject.toString().indexOf(".") != -1) { 6893 List<String> splits = SQLUtil.parseNames(columnObject.toString()); 6894 tableModel = modelFactory.createVariable(splits.get(splits.size() - 2)); 6895 } else { 6896 tableModel = modelFactory.createVariable(columnObject); 6897 } 6898 tableModel.setCreateTable(true); 6899 tableModel.setSubType(SubType.record); 6900 6901 if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) { 6902 tableColumn = modelFactory.createTableColumn(tableModel, columnObject, true); 6903 } else { 6904 tableColumn = tableModel.getColumns().get(0); 6905 } 6906 6907 if (tableColumn != null && right!=null) { 6908 columnsInExpr visitor = new columnsInExpr(); 6909 right.inOrderTraverse(visitor); 6910 List<TObjectName> objectNames = visitor.getObjectNames(); 6911 List<TParseTreeNode> functions = visitor.getFunctions(); 6912 List<TParseTreeNode> constants = visitor.getConstants(); 6913 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 6914 6915 if (functions != null && !functions.isEmpty()) { 6916 analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function); 6917 } 6918 if (subquerys != null && !subquerys.isEmpty()) { 6919 analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select); 6920 } 6921 if (objectNames != null && !objectNames.isEmpty()) { 6922 analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions); 6923 } 6924 if (constants != null && !constants.isEmpty()) { 6925 analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, functions); 6926 } 6927 6928 if(columnObject.toString().equalsIgnoreCase("search_path") && !constants.isEmpty()) { 6929 ModelBindingManager.setGlobalSchema(constants.get(0).toString()); 6930 } 6931 } 6932 } 6933 6934 if(stmt.getAssignments()!=null){ 6935 for (int i = 0; i < stmt.getAssignments().size(); i++) { 6936 TSetAssignment assignStmt = stmt.getAssignments().getElement(i); 6937 analyzeSetAssignmentStmt(assignStmt); 6938 } 6939 } 6940 } 6941 6942 private void analyzeSetAssignmentStmt(TSetAssignment stmt) { 6943 TExpression right = stmt.getParameterValue(); 6944 TObjectName columnObject = stmt.getParameterName(); 6945 if (columnObject != null) { 6946 TableColumn tableColumn = null; 6947 Variable tableModel; 6948 if (columnObject.toString().indexOf(".") != -1) { 6949 List<String> splits = SQLUtil.parseNames(columnObject.toString()); 6950 tableModel = modelFactory.createVariable(splits.get(splits.size() - 2)); 6951 } else { 6952 tableModel = modelFactory.createVariable(columnObject); 6953 } 6954 tableModel.setCreateTable(true); 6955 tableModel.setSubType(SubType.record); 6956 if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) { 6957 tableColumn = modelFactory.createTableColumn(tableModel, columnObject, true); 6958 } else { 6959 tableColumn = tableModel.getColumns().get(0); 6960 } 6961 6962 if (tableColumn != null && right!=null) { 6963 columnsInExpr visitor = new columnsInExpr(); 6964 right.inOrderTraverse(visitor); 6965 List<TObjectName> objectNames = visitor.getObjectNames(); 6966 List<TParseTreeNode> functions = visitor.getFunctions(); 6967 List<TParseTreeNode> constants = visitor.getConstants(); 6968 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 6969 6970 if (functions != null && !functions.isEmpty()) { 6971 analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function); 6972 } 6973 if (subquerys != null && !subquerys.isEmpty()) { 6974 analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select); 6975 } 6976 if (objectNames != null && !objectNames.isEmpty()) { 6977 analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions); 6978 } 6979 if (constants != null && !constants.isEmpty()) { 6980 analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, functions); 6981 } 6982 6983 if(columnObject.toString().equalsIgnoreCase("search_path") && !constants.isEmpty()) { 6984 ModelBindingManager.setGlobalSchema(constants.get(0).toString()); 6985 } 6986 } 6987 } 6988 } 6989 6990 private void analyzeMssqlSetStmt(TMssqlSet stmt) { 6991 TExpression right = stmt.getVarExpr(); 6992 TObjectName columnObject = stmt.getVarName(); 6993 if (columnObject != null) { 6994 TableColumn tableColumn = null; 6995 Variable tableModel; 6996 if (columnObject.toString().indexOf(".") != -1) { 6997 List<String> splits = SQLUtil.parseNames(columnObject.toString()); 6998 tableModel = modelFactory.createVariable(splits.get(splits.size() - 2)); 6999 } else { 7000 tableModel = modelFactory.createVariable(columnObject); 7001 } 7002 tableModel.setCreateTable(true); 7003 tableModel.setSubType(SubType.record); 7004 if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) { 7005 tableColumn = modelFactory.createTableColumn(tableModel, columnObject, true); 7006 } 7007 else { 7008 tableColumn = tableModel.getColumns().get(0); 7009 } 7010 7011 if (tableColumn != null && right!=null) { 7012 columnsInExpr visitor = new columnsInExpr(); 7013 right.inOrderTraverse(visitor); 7014 List<TObjectName> objectNames = visitor.getObjectNames(); 7015 List<TParseTreeNode> functions = visitor.getFunctions(); 7016 List<TParseTreeNode> constants = visitor.getConstants(); 7017 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 7018 7019 if (functions != null && !functions.isEmpty()) { 7020 analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function); 7021 } 7022 if (subquerys != null && !subquerys.isEmpty()) { 7023 analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select); 7024 } 7025 if (objectNames != null && !objectNames.isEmpty()) { 7026 analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions); 7027 } 7028 if (constants != null && !constants.isEmpty()) { 7029 analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, functions); 7030 } 7031 7032 if(columnObject.toString().equalsIgnoreCase("search_path") && !constants.isEmpty()) { 7033 ModelBindingManager.setGlobalSchema(constants.get(0).toString()); 7034 } 7035 } 7036 else if(tableColumn!=null && stmt.getSubquery()!=null){ 7037 analyzeCustomSqlStmt(stmt.getSubquery()); 7038 analyzeSubqueryDataFlowRelation(tableColumn, Arrays.asList(stmt.getSubquery()), EffectType.select); 7039 } 7040 } 7041 } 7042 7043 private void analyzeAssignStmt(TAssignStmt stmt) { 7044 TExpression left = stmt.getLeft(); 7045 TExpression right = stmt.getExpression(); 7046 TObjectName columnObject = null; 7047 if (left == null) { 7048 columnObject = stmt.getVariableName(); 7049 } else if (left.getExpressionType() == EExpressionType.simple_object_name_t) { 7050 columnObject = left.getObjectOperand(); 7051 } 7052 if (columnObject != null) { 7053 TableColumn tableColumn = null; 7054 if (columnObject.getDbObjectType() == EDbObjectType.variable || stmt.getVariableName() != null) { 7055 Variable tableModel; 7056 if (columnObject.toString().indexOf(".") != -1) { 7057 List<String> splits = SQLUtil.parseNames(columnObject.toString()); 7058 tableModel = modelFactory.createVariable(splits.get(splits.size() - 2)); 7059 } else { 7060 tableModel = modelFactory.createVariable(columnObject); 7061 } 7062 tableModel.setCreateTable(true); 7063 tableModel.setSubType(SubType.record); 7064 if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) { 7065 tableColumn = modelFactory.createTableColumn(tableModel, columnObject, true); 7066 } else { 7067 tableColumn = tableModel.getColumns().get(0); 7068 } 7069 } else { 7070 List<String> splits = SQLUtil.parseNames(columnObject.toString()); 7071 if (splits.size() > 1) { 7072 Table tableModel = modelManager 7073 .getTableByName(DlineageUtil.getTableFullName(splits.get(splits.size() - 2))); 7074 if (tableModel == null) { 7075 String procedureName = DlineageUtil.getProcedureParentName(stmt); 7076 String variableString = splits.get(splits.size() - 2).toString(); 7077 if (variableString.startsWith(":")) { 7078 variableString = variableString.substring(variableString.indexOf(":") + 1); 7079 } 7080 if (!SQLUtil.isEmpty(procedureName)) { 7081 variableString = procedureName + "." + SQLUtil.getIdentifierNormalTableName(variableString); 7082 } 7083 tableModel = modelManager.getTableByName(DlineageUtil.getTableFullName(variableString)); 7084 } 7085 if (tableModel != null) { 7086 tableColumn = modelFactory.createTableColumn(tableModel, columnObject, true); 7087 } 7088 } 7089 } 7090 7091 if (tableColumn != null && right != null) { 7092 Transform transform = new Transform(); 7093 transform.setType(Transform.EXPRESSION); 7094 transform.setCode(right); 7095 tableColumn.setTransform(transform);; 7096 columnsInExpr visitor = new columnsInExpr(); 7097 right.inOrderTraverse(visitor); 7098 List<TObjectName> objectNames = visitor.getObjectNames(); 7099 List<TParseTreeNode> functions = visitor.getFunctions(); 7100 List<TParseTreeNode> constants = visitor.getConstants(); 7101 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 7102 7103 if (functions != null && !functions.isEmpty()) { 7104 analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function); 7105 } 7106 if (subquerys != null && !subquerys.isEmpty()) { 7107 analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select); 7108 } 7109 if (objectNames != null && !objectNames.isEmpty()) { 7110 analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions); 7111 } 7112 if (constants != null && !constants.isEmpty()) { 7113 analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, functions); 7114 } 7115 } 7116 } 7117 } 7118 7119 private void analyzeOpenForStmt(TOpenforStmt stmt) { 7120 if (stmt.getSubquery() == null) { 7121 return; 7122 } 7123 7124 Variable cursorTempTable = modelFactory.createCursor(stmt); 7125 cursorTempTable.setVariable(true); 7126 cursorTempTable.setSubType(SubType.cursor); 7127 modelManager.bindCursorModel(stmt, cursorTempTable); 7128 analyzeSelectStmt(stmt.getSubquery()); 7129 7130 TableColumn cursorColumn = null; 7131 if (cursorTempTable.getColumns() == null || cursorTempTable.getColumns().isEmpty()) { 7132 TObjectName starColumn = new TObjectName(); 7133 starColumn.setString("*"); 7134 cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true); 7135 } else { 7136 cursorColumn = cursorTempTable.getColumns().get(0); 7137 } 7138 7139 ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubquery()); 7140 if (resultSetModel != null) { 7141 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 7142 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 7143 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 7144 dataflowRelation.setEffectType(EffectType.cursor); 7145 dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7146 dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn)); 7147 } 7148 } 7149 } 7150 7151 private void analyzeCursorDeclStmt(TCursorDeclStmt stmt) { 7152 if (stmt.getSubquery() == null) { 7153 return; 7154 } 7155 7156 Variable cursorTempTable = modelFactory.createCursor(stmt); 7157 cursorTempTable.setVariable(true); 7158 cursorTempTable.setSubType(SubType.cursor); 7159 modelManager.bindCursorModel(stmt, cursorTempTable); 7160 analyzeSelectStmt(stmt.getSubquery()); 7161 7162 ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubquery()); 7163 if(resultSetModel!=null && resultSetModel.isDetermined()) { 7164 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 7165 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 7166 TObjectName columnName = new TObjectName(); 7167 columnName.setString(resultColumn.getName()); 7168 TableColumn cursorColumn = modelFactory.createTableColumn(cursorTempTable, columnName, true); 7169 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 7170 dataflowRelation.setEffectType(EffectType.cursor); 7171 dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7172 dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn)); 7173 } 7174 } 7175 else { 7176 TableColumn cursorColumn = null; 7177 if (cursorTempTable.getColumns() == null || cursorTempTable.getColumns().isEmpty()) { 7178 TObjectName starColumn = new TObjectName(); 7179 starColumn.setString("*"); 7180 cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true); 7181 } else { 7182 cursorColumn = cursorTempTable.getColumns().get(0); 7183 } 7184 if (resultSetModel != null) { 7185 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 7186 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 7187 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 7188 dataflowRelation.setEffectType(EffectType.cursor); 7189 dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7190 dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn)); 7191 } 7192 } 7193 } 7194 7195 } 7196 7197 private void analyzeDb2Declare(TDb2SqlVariableDeclaration stmt) { 7198 TDeclareVariableList variables = stmt.getVariables(); 7199 if (variables == null) { 7200 return; 7201 } 7202 for (int i = 0; i < variables.size(); i++) { 7203 TDeclareVariable variable = variables.getDeclareVariable(i); 7204 if (variable.getTableTypeDefinitions() != null && variable.getTableTypeDefinitions().size() > 0) { 7205 7206 7207 TObjectName tableName = variable.getVariableName(); 7208 TTableElementList columns = variable.getTableTypeDefinitions(); 7209 7210 Table tableModel = modelFactory.createTableByName(tableName, true); 7211 tableModel.setCreateTable(true); 7212 String procedureParent = getProcedureParentName(stmt); 7213 if (procedureParent != null) { 7214 tableModel.setParent(procedureParent); 7215 } 7216 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), tableModel); 7217 7218 for (int j = 0; j < columns.size(); j++) { 7219 TTableElement tableElement = columns.getTableElement(j); 7220 TColumnDefinition column = tableElement.getColumnDefinition(); 7221 if (column != null && column.getColumnName() != null) { 7222 modelFactory.createTableColumn(tableModel, column.getColumnName(), true); 7223 } 7224 } 7225 } else if (variable.getVariableName() != null) { 7226 Variable cursorVariable = modelFactory.createVariable(variable.getVariableName()); 7227 cursorVariable.setCreateTable(true); 7228 cursorVariable.setSubType(SubType.record); 7229 if(variable.getDatatype()!=null && isSimpleDataType(variable.getDatatype())){ 7230 TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable, 7231 variable.getVariableName(), true); 7232 } 7233 else { 7234 TObjectName variableProperties = new TObjectName(); 7235 variableProperties.setString("*"); 7236 TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable, 7237 variableProperties, true); 7238 } 7239 } 7240 } 7241 } 7242 7243 private void analyzeMssqlDeclare(TMssqlDeclare stmt) { 7244 if (stmt.getDeclareType() == EDeclareType.variable) { 7245 TDeclareVariableList variables = stmt.getVariables(); 7246 if (variables == null) { 7247 return; 7248 } 7249 for (int i = 0; i < variables.size(); i++) { 7250 TDeclareVariable variable = variables.getDeclareVariable(i); 7251 if (variable.getTableTypeDefinitions() != null && variable.getTableTypeDefinitions().size() > 0) { 7252 7253 7254 TObjectName tableName = variable.getVariableName(); 7255 TTableElementList columns = variable.getTableTypeDefinitions(); 7256 7257 Variable tableModel = modelFactory.createVariable(tableName); 7258 tableModel.setVariable(true); 7259 tableModel.setCreateTable(true); 7260 String procedureParent = getProcedureParentName(stmt); 7261 if (procedureParent != null) { 7262 tableModel.setParent(procedureParent); 7263 } 7264 modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), tableModel); 7265 7266 for (int j = 0; j < columns.size(); j++) { 7267 TTableElement tableElement = columns.getTableElement(j); 7268 TColumnDefinition column = tableElement.getColumnDefinition(); 7269 if (column != null && column.getColumnName() != null) { 7270 modelFactory.createTableColumn(tableModel, column.getColumnName(), true); 7271 } 7272 } 7273 } else if (variable.getVariableName() != null) { 7274 Variable cursorVariable = modelFactory.createVariable(variable.getVariableName()); 7275 cursorVariable.setCreateTable(true); 7276 cursorVariable.setSubType(SubType.record); 7277 TableColumn variableProperty = null; 7278 if (variable.getDatatype() != null && isSimpleDataType(variable.getDatatype())) { 7279 variableProperty = modelFactory.createTableColumn(cursorVariable, variable.getVariableName(), 7280 true); 7281 } else { 7282 TObjectName variableProperties = new TObjectName(); 7283 variableProperties.setString("*"); 7284 variableProperty = modelFactory.createTableColumn(cursorVariable, variableProperties, true); 7285 } 7286 7287 if (variable.getDefaultValue() != null && variable.getDefaultValue().getSubQuery() != null) { 7288 analyzeSelectStmt(variable.getDefaultValue().getSubQuery()); 7289 ResultSet resultSetModel = (ResultSet) modelManager 7290 .getModel(variable.getDefaultValue().getSubQuery()); 7291 if (variableProperty != null && resultSetModel != null) { 7292 for (ResultColumn column : resultSetModel.getColumns()) { 7293 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 7294 dataflowRelation.setEffectType(EffectType.select); 7295 dataflowRelation.addSource(new ResultColumnRelationshipElement(column)); 7296 dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty)); 7297 } 7298 } 7299 } 7300 } 7301 } 7302 } else if (stmt.getDeclareType() == EDeclareType.cursor) { 7303 Variable cursorTempTable = modelFactory.createCursor(stmt); 7304 cursorTempTable.setVariable(true); 7305 cursorTempTable.setSubType(SubType.cursor); 7306 modelManager.bindCursorModel(stmt, cursorTempTable); 7307 analyzeSelectStmt(stmt.getSubquery()); 7308 ResultSet resultSetModel = (ResultSet)modelManager.getModel(stmt.getSubquery()); 7309 if (resultSetModel != null && resultSetModel.isDetermined()) { 7310 for(ResultColumn resultColumn: resultSetModel.getColumns()){ 7311 TObjectName starColumn = new TObjectName(); 7312 starColumn.setString(resultColumn.getName()); 7313 TableColumn cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true); 7314 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 7315 dataflowRelation.setEffectType(EffectType.cursor); 7316 dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7317 dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn)); 7318 } 7319 } 7320 else { 7321 TableColumn cursorColumn = null; 7322 if (cursorTempTable.getColumns() == null || cursorTempTable.getColumns().isEmpty()) { 7323 TObjectName starColumn = new TObjectName(); 7324 starColumn.setString("*"); 7325 cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true); 7326 cursorColumn.setShowStar(false); 7327 cursorColumn.setExpandStar(true); 7328 } else { 7329 cursorColumn = cursorTempTable.getColumns().get(0); 7330 } 7331 7332 if (resultSetModel != null) { 7333 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 7334 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 7335 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 7336 dataflowRelation.setEffectType(EffectType.cursor); 7337 dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7338 dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn)); 7339 } 7340 } 7341 } 7342 } 7343 } 7344 7345 7346 private boolean analyzeMssqlJsonDeclare(TMssqlDeclare stmt, String jsonName, Table jsonTable) { 7347 TDeclareVariableList variables = stmt.getVariables(); 7348 if (variables == null) { 7349 return false; 7350 } 7351 for (int i = 0; i < variables.size(); i++) { 7352 TDeclareVariable variable = variables.getDeclareVariable(i); 7353 TObjectName variableName = variable.getVariableName(); 7354 if (DlineageUtil.getIdentifierNormalTableName(variableName.toString()) 7355 .equals(DlineageUtil.getIdentifierNormalTableName(jsonName))) { 7356 if (variable.getDefaultValue() != null) { 7357 Table variableTable = modelFactory.createJsonVariable(variableName); 7358 variableTable.setVariable(true); 7359 variableTable.setSubType(SubType.scalar); 7360 variableTable.setCreateTable(true); 7361 TableColumn property = modelFactory.createVariableProperty(variableTable, variable); 7362 7363 for (int j = 0; j < jsonTable.getColumns().size(); j++) { 7364 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7365 relation.setEffectType(EffectType.select); 7366 relation.setTarget(new TableColumnRelationshipElement(jsonTable.getColumns().get(j))); 7367 relation.addSource(new TableColumnRelationshipElement(property)); 7368 } 7369 } 7370 return true; 7371 } 7372 } 7373 return false; 7374 } 7375 7376 private void analyzeCreateTableStmt(TCreateTableSqlStatement stmt) { 7377 if (stmt.getCloneSourceTable() != null) { 7378 analyzeCloneTableStmt(stmt); 7379 return; 7380 } 7381 7382 TTable table = stmt.getTargetTable(); 7383 7384 boolean hasDefinition = false; 7385 7386 if (stmt.getColumnList() != null && stmt.getColumnList().size() > 0) { 7387 hasDefinition = true; 7388 } 7389 7390 if (table != null) { 7391 Table tableModel = modelFactory.createTableFromCreateDDL(table, hasDefinition || (stmt.getSubQuery() == null && hasDefinition) 7392 || (stmt.getSubQuery()!=null && stmt.getSubQuery().getSetOperatorType() == ESetOperatorType.none && stmt.getSubQuery().getResultColumnList().toString().indexOf("*") == -1)); 7393 // Authoritative create-effect classification (parse fact, NOT gated on 7394 // isDetermined() like fromDDL below). CTAS when there is a defining query, 7395 // plain DDL otherwise. See dlineage-authoritative-endpoint-classification.md. 7396 tableModel.setCreatedInSql(true); 7397 tableModel.setEndpointIntroduction(stmt.getSubQuery() != null 7398 ? EndpointIntroduction.CTAS : EndpointIntroduction.CREATE_TABLE_DDL); 7399 if (stmt.isExternal()) { 7400 tableModel.setExternal(true); 7401 } 7402 7403 if (stmt.getSubQuery() != null) { 7404 Process process = modelFactory.createProcess(stmt); 7405 tableModel.addProcess(process); 7406 } 7407 7408 String procedureParent = getProcedureParentName(stmt); 7409 if (procedureParent != null) { 7410 tableModel.setParent(procedureParent); 7411 } 7412 7413 if (stmt.isUsingTemplate()) { 7414 // Snowflake CREATE TABLE ... USING TEMPLATE <query>: the query only 7415 // infers the column definitions (e.g. ARRAY_AGG(OBJECT_CONSTRUCT(*)) 7416 // over INFER_SCHEMA); it does NOT populate the table. Analyze it so its 7417 // own sources (the stage / INFER_SCHEMA) still resolve, but do not 7418 // project its result columns onto the target table or emit CTAS-style 7419 // data-flow edges that would misrepresent it as data population. 7420 if (stmt.getSubQuery() != null) { 7421 analyzeSelectStmt(stmt.getSubQuery()); 7422 } 7423 return; 7424 } 7425 7426 if (hasDefinition) { 7427 if(stmt.getSubQuery()!=null) { 7428 TSelectSqlStatement subquery = stmt.getSubQuery(); 7429 analyzeSelectStmt(subquery); 7430 Process process = modelFactory.createProcess(stmt); 7431 ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubQuery()); 7432 if(resultSetModel.isDetermined()){ 7433 tableModel.setFromDDL(true); 7434 } 7435 if (resultSetModel != null) { 7436 int resultSetSize = resultSetModel.getColumns().size(); 7437 int stmtColumnSize = stmt.getColumnList().size(); 7438 int j = 0; 7439 int tableColumnSize = stmtColumnSize; 7440 if (resultSetModel.isDetermined() && resultSetSize > tableColumnSize) { 7441 tableColumnSize = resultSetSize; 7442 } 7443 for (int i = 0; i < tableColumnSize && j < resultSetSize; i++) { 7444 ResultColumn resultColumn = resultSetModel.getColumns().get(j); 7445 if (i < stmtColumnSize) { 7446 TObjectName alias = stmt.getColumnList().getColumn(i).getColumnName(); 7447 7448 if (!resultSetModel.getColumns().get(j).getName().contains("*")) { 7449 j++; 7450 } else { 7451 if (resultSetSize - j == stmt.getColumnList().size() - i) { 7452 j++; 7453 } 7454 } 7455 7456 if (alias != null) { 7457 TableColumn viewColumn = modelFactory.createTableColumn(tableModel, alias, true); 7458 if (resultColumn != null) { 7459 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7460 relation.setEffectType(EffectType.create_table); 7461 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 7462 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7463 relation.setProcess(process); 7464 } 7465 } else if (resultColumn.getColumnObject() instanceof TObjectName) { 7466 TableColumn viewColumn = modelFactory.createTableColumn(tableModel, 7467 (TObjectName) resultColumn.getColumnObject(), true); 7468 if (resultColumn != null) { 7469 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7470 relation.setEffectType(EffectType.create_table); 7471 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 7472 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7473 relation.setProcess(process); 7474 } 7475 } else if (resultColumn.getColumnObject() instanceof TResultColumn) { 7476 TableColumn viewColumn = modelFactory.createTableColumn(tableModel, 7477 ((TResultColumn) resultColumn.getColumnObject()).getFieldAttr(), true); 7478 ResultColumn column = (ResultColumn) modelManager 7479 .getModel(resultColumn.getColumnObject()); 7480 if (column != null && !column.getStarLinkColumns().isEmpty()) { 7481 viewColumn.bindStarLinkColumns(column.getStarLinkColumns()); 7482 } 7483 if (resultColumn != null) { 7484 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7485 relation.setEffectType(EffectType.create_table); 7486 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 7487 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7488 relation.setProcess(process); 7489 } 7490 } 7491 } 7492 else if(resultSetModel.isDetermined()){ 7493 TObjectName tableName = new TObjectName(); 7494 tableName.setString(resultColumn.getName()); 7495 TableColumn viewColumn = modelFactory.createTableColumn(tableModel, tableName, true); 7496 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7497 relation.setEffectType(EffectType.create_table); 7498 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 7499 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7500 relation.setProcess(process); 7501 j++; 7502 } 7503 } 7504 if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 7505 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 7506 impactRelation.setEffectType(EffectType.create_table); 7507 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 7508 resultSetModel.getRelationRows())); 7509 impactRelation.setTarget( 7510 new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows())); 7511 } 7512 } 7513 7514 if (subquery.getResultColumnList() == null && subquery.getValueClause() != null 7515 && subquery.getValueClause().getValueRows().size() == stmt.getColumnList().size()) { 7516 for (int i = 0; i < stmt.getColumnList().size(); i++) { 7517 TObjectName alias = stmt.getColumnList().getColumn(i).getColumnName(); 7518 7519 if (alias != null) { 7520 TableColumn viewColumn = modelFactory.createTableColumn(tableModel, alias, true); 7521 7522 TExpression expression = subquery.getValueClause().getValueRows().getValueRowItem(i).getExpr(); 7523 7524 columnsInExpr visitor = new columnsInExpr(); 7525 expression.inOrderTraverse(visitor); 7526 List<TObjectName> objectNames = visitor.getObjectNames(); 7527 List<TParseTreeNode> functions = visitor.getFunctions(); 7528 7529 if (functions != null && !functions.isEmpty()) { 7530 analyzeFunctionDataFlowRelation(viewColumn, functions, EffectType.select); 7531 7532 } 7533 7534 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 7535 if (subquerys != null && !subquerys.isEmpty()) { 7536 analyzeSubqueryDataFlowRelation(viewColumn, subquerys, EffectType.select); 7537 } 7538 7539 analyzeDataFlowRelation(viewColumn, objectNames, EffectType.select, functions); 7540 List<TParseTreeNode> constants = visitor.getConstants(); 7541 analyzeConstantDataFlowRelation(viewColumn, constants, EffectType.select, functions); 7542 } 7543 } 7544 } 7545 7546 return; 7547 } 7548 else { 7549 for (int i = 0; i < stmt.getColumnList().size(); i++) { 7550 TColumnDefinition column = stmt.getColumnList().getColumn(i); 7551 if (column.getDatatype() != null && column.getDatatype().getTypeOfList() != null 7552 && column.getDatatype().getTypeOfList().getColumnDefList() != null) { 7553 for (int j = 0; j < column.getDatatype().getTypeOfList().getColumnDefList().size(); j++) { 7554 TObjectName columnName = new TObjectName(); 7555 if (column.getDatatype().getDataType() == EDataType.array_t) { 7556// columnName.setString(column.getColumnName().getColumnNameOnly() + ".array." 7557// + column.getDatatype().getTypeOfList().getColumnDefList().getColumn(j) 7558// .getColumnName().getColumnNameOnly()); 7559 columnName.setString(column.getColumnName().getColumnNameOnly() + "." 7560 + column.getDatatype().getTypeOfList().getColumnDefList().getColumn(j) 7561 .getColumnName().getColumnNameOnly()); 7562 } else { 7563 columnName.setString(column.getColumnName().getColumnNameOnly() + "." 7564 + column.getDatatype().getTypeOfList().getColumnDefList().getColumn(j) 7565 .getColumnName().getColumnNameOnly()); 7566 } 7567 TableColumn tableColumn = modelFactory.createTableColumn(tableModel, columnName, 7568 hasDefinition); 7569 tableColumn.setStruct(true); 7570 tableColumn.setColumnIndex(i); 7571 appendTableColumnToSQLEnv(tableModel, tableColumn); 7572 7573 if(option.getAnalyzeMode() == AnalyzeMode.crud) { 7574 CrudRelationship crudRelationship = modelFactory.createCrudRelation(); 7575 crudRelationship.setTarget(new TableColumnRelationshipElement(tableColumn)); 7576 crudRelationship.setEffectType(EffectType.create_table); 7577 } 7578 } 7579 continue; 7580 } 7581 if (column.getDatatype() != null && column.getDatatype().getColumnDefList() != null) { 7582 Stack<TColumnDefinition> columnPaths = new Stack<TColumnDefinition>(); 7583 flattenStructColumns(hasDefinition, tableModel, column, columnPaths, i); 7584 continue; 7585 } 7586 TableColumn tableColumn = modelFactory.createTableColumn(tableModel, column.getColumnName(), 7587 hasDefinition); 7588 if (tableColumn == null) { 7589 continue; 7590 } 7591 7592 if(option.getAnalyzeMode() == AnalyzeMode.crud) { 7593 CrudRelationship crudRelationship = modelFactory.createCrudRelation(); 7594 crudRelationship.setTarget(new TableColumnRelationshipElement(tableColumn)); 7595 crudRelationship.setEffectType(EffectType.create_table); 7596 } 7597 7598 if (column.getDatatype() != null && column.getDatatype().getDataType() == EDataType.variant_t) { 7599 if (tableColumn != null) { 7600 tableColumn.setVariant(true); 7601 } 7602 } 7603 if (column.getDatatype() != null) { 7604 String dType = column.getDatatype().getDataTypeName(); 7605 if ((!SQLUtil.isEmpty(dType)) && (dType.indexOf("_") > 0)) { 7606 dType = dType.split("_")[0]; 7607 } 7608 tableColumn.setDataType(dType); 7609 } 7610 7611 // Inline (column-level) PK / FK constraint FLAGS. The 7612 // table-level pass below (stmt.getTableConstraints()) 7613 // never sees inline constraints, so set the flags here. 7614 // Without this, "id INTEGER PRIMARY KEY" or 7615 // "fk INTEGER REFERENCES t (c)" produced no 7616 // isPrimaryKey()/isForeignKey() flag, unlike the 7617 // equivalent table-level CONSTRAINT form. 7618 // EConstraintType.reference is the inline REFERENCES 7619 // form; foreign_key is the (rare) inline FOREIGN KEY. 7620 // Only flags are set here (no model objects allocated) 7621 // so column ids are unchanged; the FK relationship 7622 // edges are emitted in a deferred pass after the column 7623 // loop (see "inline FK relationships" below), matching 7624 // the table-level pass ordering so ids stay stable. 7625 TConstraintList inlineConstraints = column.getConstraints(); 7626 if (inlineConstraints != null) { 7627 for (int c = 0; c < inlineConstraints.size(); c++) { 7628 EConstraintType inlineType = inlineConstraints.getConstraint(c) 7629 .getConstraint_type(); 7630 if (inlineType == EConstraintType.primary_key) { 7631 tableColumn.setPrimaryKey(true); 7632 } else if (inlineType == EConstraintType.foreign_key 7633 || inlineType == EConstraintType.reference) { 7634 tableColumn.setForeignKey(true); 7635 } 7636 } 7637 } 7638 7639 appendTableColumnToSQLEnv(tableModel, tableColumn); 7640 } 7641 } 7642 } 7643 7644 if (stmt.getExternalTableOption("DATA_SOURCE") != null) { 7645 String dataSourceName = stmt.getExternalTableOption("DATA_SOURCE"); 7646 Table dataSource = modelManager.getTableByName(DlineageUtil.getTableFullName(dataSourceName)); 7647 if (dataSource != null) { 7648 TableColumn dataSourceColumn = dataSource.getColumns().get(0); 7649 for (int i = 0; i < tableModel.getColumns().size(); i++) { 7650 TableColumn column = tableModel.getColumns().get(i); 7651 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7652 relation.setTarget(new TableColumnRelationshipElement(column)); 7653 relation.addSource(new TableColumnRelationshipElement(dataSourceColumn)); 7654 7655 appendTableColumnToSQLEnv(tableModel, column); 7656 } 7657 } 7658 } 7659 7660 if (stmt.getSubQuery() != null) { 7661 7662 analyzeSelectStmt(stmt.getSubQuery()); 7663 7664 ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubQuery()); 7665 if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 7666 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 7667 impactRelation.setEffectType(EffectType.create_table); 7668 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 7669 resultSetModel.getRelationRows())); 7670 impactRelation.setTarget( 7671 new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows())); 7672 } 7673 } 7674 7675 if (stmt.getSubQuery() != null && !stmt.getSubQuery().isCombinedQuery()) { 7676 SelectResultSet resultSetModel = (SelectResultSet) modelManager 7677 .getModel(stmt.getSubQuery().getResultColumnList()); 7678 if(resultSetModel.isDetermined()){ 7679 tableModel.setDetermined(true); 7680 tableModel.setFromDDL(true); 7681 } 7682 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 7683 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 7684 if (resultSetModel.isDetermined() && resultColumn.getName().endsWith("*")) { 7685 continue; 7686 } 7687 7688 if (resultColumn.getColumnObject() instanceof TResultColumn) { 7689 TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject(); 7690 7691 TAliasClause alias = columnObject.getAliasClause(); 7692 if (alias != null && alias.getAliasName() != null) { 7693 TableColumn tableColumn = null; 7694 if (!hasDefinition) { 7695 tableColumn = modelFactory.createTableColumn(tableModel, alias.getAliasName(), 7696 !hasDefinition); 7697 } else { 7698 tableColumn = tableModel.getColumns().get(i); 7699 } 7700 7701 if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) { 7702 appendTableColumnToSQLEnv(tableModel, tableColumn); 7703 } 7704 7705 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7706 relation.setEffectType(EffectType.create_table); 7707 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7708 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7709 Process process = modelFactory.createProcess(stmt); 7710 relation.setProcess(process); 7711 } else if (columnObject.getFieldAttr() != null || (columnObject.getExpr()!=null && columnObject.getExpr().getExpressionType() == EExpressionType.typecast_t)) { 7712 TableColumn tableColumn = null; 7713 TObjectName columnObj = columnObject.getFieldAttr(); 7714 if(columnObj == null) { 7715 columnObj = columnObject.getExpr().getLeftOperand().getObjectOperand(); 7716 } 7717 if ((columnObj == null || columnObj.toString().endsWith("*")) && !resultColumn.getName().endsWith("*")) { 7718 columnObj = new TObjectName(); 7719 columnObj.setString(resultColumn.getName()); 7720 } 7721 7722 if(columnObj == null){ 7723 logger.info("Can't handle column " + resultColumn.getName()); 7724 continue; 7725 } 7726 7727 if (!hasDefinition) { 7728 tableColumn = modelFactory.createTableColumn(tableModel, columnObj, 7729 !hasDefinition); 7730 if (tableColumn == null) { 7731 if (tableModel.getColumns().isEmpty()) { 7732 logger.info("Add table " + tableModel.getName() + " column " + columnObj.toString() + " failed"); 7733 } 7734 else if (resultColumn.getName().endsWith("*")) { 7735 for (int j = 0; j < tableModel.getColumns().size(); j++) { 7736 tableColumn = tableModel.getColumns().get(j); 7737 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7738 relation.setEffectType(EffectType.create_table); 7739 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7740 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7741 if (tableColumn.getName().endsWith("*") 7742 && resultColumn.getName().endsWith("*")) { 7743 tableModel.setStarStmt("create_table"); 7744 } 7745 Process process = modelFactory.createProcess(stmt); 7746 relation.setProcess(process); 7747 } 7748 } 7749 continue; 7750 } 7751 if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) { 7752 appendTableColumnToSQLEnv(tableModel, tableColumn); 7753 } 7754 7755 Object model = modelManager 7756 .getModel(resultColumn.getColumnObject()); 7757 if (model instanceof ResultColumn) { 7758 ResultColumn column = (ResultColumn) model; 7759 if (tableColumn.getName().endsWith("*") && column != null 7760 && !column.getStarLinkColumns().isEmpty()) { 7761 tableColumn.bindStarLinkColumns(column.getStarLinkColumns()); 7762 } 7763 7764 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7765 relation.setEffectType(EffectType.create_table); 7766 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7767 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7768 if (tableColumn.getName().endsWith("*") && resultColumn.getName().endsWith("*")) { 7769 tableModel.setStarStmt("create_table"); 7770 } 7771 Process process = modelFactory.createProcess(stmt); 7772 relation.setProcess(process); 7773 } 7774 else if(model instanceof LinkedHashMap) { 7775 String columnName = getColumnNameOnly(resultColumn.getName()); 7776 LinkedHashMap<String, ResultColumn> resultColumns = (LinkedHashMap<String, ResultColumn>)model; 7777 if (columnObj.toString().endsWith("*")) { 7778 for (String key : resultColumns.keySet()) { 7779 tableColumn = modelFactory.createInsertTableColumn(tableModel, resultColumns.get(key).getName()); 7780 DataFlowRelationship relation = modelFactory 7781 .createDataFlowRelation(); 7782 relation.setEffectType(EffectType.create_table); 7783 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7784 relation.addSource( 7785 new ResultColumnRelationshipElement(resultColumns.get(key))); 7786 Process process = modelFactory.createProcess(stmt); 7787 relation.setProcess(process); 7788 } 7789 } else if (resultColumns.containsKey(columnName)) { 7790 ResultColumn column = resultColumns.get(columnName); 7791 tableColumn = modelFactory.createInsertTableColumn(tableModel, column.getName()); 7792 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7793 relation.setEffectType(EffectType.create_table); 7794 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7795 relation.addSource(new ResultColumnRelationshipElement(column)); 7796 Process process = modelFactory.createProcess(stmt); 7797 relation.setProcess(process); 7798 } 7799 } 7800 } else { 7801 if (resultColumn.getName().endsWith("*")) { 7802 for (int j = 0; j < tableModel.getColumns().size(); j++) { 7803 tableColumn = tableModel.getColumns().get(j); 7804 ResultColumn column = (ResultColumn) modelManager 7805 .getModel(resultColumn.getColumnObject()); 7806 if (tableColumn.getName().endsWith("*") && column != null 7807 && !column.getStarLinkColumns().isEmpty()) { 7808 tableColumn.bindStarLinkColumns(column.getStarLinkColumns()); 7809 } 7810 7811 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7812 relation.setEffectType(EffectType.create_table); 7813 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7814 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7815 if (tableColumn.getName().endsWith("*") 7816 && resultColumn.getName().endsWith("*")) { 7817 tableModel.setStarStmt("create_table"); 7818 ; 7819 } 7820 Process process = modelFactory.createProcess(stmt); 7821 relation.setProcess(process); 7822 } 7823 } else { 7824 tableColumn = tableModel.getColumns().get(i); 7825 Object model = modelManager 7826 .getModel(resultColumn.getColumnObject()); 7827 String columnName = getColumnNameOnly(resultColumn.getName()); 7828 if(model instanceof LinkedHashMap) { 7829 LinkedHashMap<String, ResultColumn> resultColumns = (LinkedHashMap<String, ResultColumn>)model; 7830 if (resultColumns.size() == tableModel.getColumns().size()) { 7831 int j = 0; 7832 for (String key : resultColumns.keySet()) { 7833 if (j == i) { 7834 ResultColumn column = resultColumns.get(key); 7835 DataFlowRelationship relation = modelFactory 7836 .createDataFlowRelation(); 7837 relation.setEffectType(EffectType.create_table); 7838 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7839 relation.addSource(new ResultColumnRelationshipElement(column)); 7840 Process process = modelFactory.createProcess(stmt); 7841 relation.setProcess(process); 7842 } 7843 j++; 7844 } 7845 } else if (resultColumns.containsKey(columnName)) { 7846 ResultColumn column = resultColumns.get(columnName); 7847 tableColumn = modelFactory.createInsertTableColumn(tableModel, column.getName()); 7848 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7849 relation.setEffectType(EffectType.create_table); 7850 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7851 relation.addSource(new ResultColumnRelationshipElement(column)); 7852 Process process = modelFactory.createProcess(stmt); 7853 relation.setProcess(process); 7854 } else { 7855 throw new UnsupportedOperationException("Can't handle this star case."); 7856 } 7857 } 7858 else if (model instanceof ResultColumn) { 7859 ResultColumn column = (ResultColumn) modelManager 7860 .getModel(resultColumn.getColumnObject()); 7861 if (tableColumn.getName().endsWith("*") && column != null 7862 && !column.getStarLinkColumns().isEmpty()) { 7863 tableColumn.bindStarLinkColumns(column.getStarLinkColumns()); 7864 } 7865 7866 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7867 relation.setEffectType(EffectType.create_table); 7868 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7869 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7870 if (tableColumn.getName().endsWith("*") 7871 && resultColumn.getName().endsWith("*")) { 7872 tableModel.setStarStmt("create_table"); 7873 } 7874 Process process = modelFactory.createProcess(stmt); 7875 relation.setProcess(process); 7876 } 7877 } 7878 } 7879 } else { 7880 TableColumn tableColumn = null; 7881 if (!hasDefinition) { 7882 TObjectName columnName = new TObjectName(); 7883 columnName.setString(resultColumn.getColumnObject().toString()); 7884 tableColumn = modelFactory.createTableColumn(tableModel, columnName, !hasDefinition); 7885 if(tableColumn == null){ 7886 continue; 7887 } 7888 } else { 7889 tableColumn = tableModel.getColumns().get(i); 7890 } 7891 ResultColumn column = (ResultColumn) modelManager.getModel(resultColumn.getColumnObject()); 7892 if (column != null && !column.getStarLinkColumns().isEmpty()) { 7893 tableColumn.bindStarLinkColumns(column.getStarLinkColumns()); 7894 } 7895 7896 if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) { 7897 appendTableColumnToSQLEnv(tableModel, tableColumn); 7898 } 7899 7900 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7901 relation.setEffectType(EffectType.create_table); 7902 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7903 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7904 Process process = modelFactory.createProcess(stmt); 7905 relation.setProcess(process); 7906 } 7907 } else if (resultColumn.getColumnObject() instanceof TObjectName) { 7908 TableColumn tableColumn = null; 7909 if (!hasDefinition) { 7910 tableColumn = modelFactory.createTableColumn(tableModel, 7911 (TObjectName) resultColumn.getColumnObject(), !hasDefinition); 7912 } else { 7913 tableColumn = tableModel.getColumns().get(i); 7914 } 7915 7916 if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) { 7917 appendTableColumnToSQLEnv(tableModel, tableColumn); 7918 } 7919 7920 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7921 relation.setEffectType(EffectType.create_table); 7922 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7923 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7924 Process process = modelFactory.createProcess(stmt); 7925 relation.setProcess(process); 7926 } 7927 } 7928 } else if (stmt.getSubQuery() != null) { 7929 SelectSetResultSet resultSetModel = (SelectSetResultSet) modelManager.getModel(stmt.getSubQuery()); 7930 if(resultSetModel.isDetermined()){ 7931 tableModel.setDetermined(true); 7932 tableModel.setFromDDL(true); 7933 } 7934 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 7935 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 7936 if (resultColumn.getColumnObject() instanceof TResultColumn) { 7937 TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject(); 7938 7939 TAliasClause alias = columnObject.getAliasClause(); 7940 if (alias != null && alias.getAliasName() != null) { 7941 TableColumn tableColumn = null; 7942 if (!hasDefinition) { 7943 tableColumn = modelFactory.createTableColumn(tableModel, alias.getAliasName(), 7944 !hasDefinition); 7945 if (tableColumn == null) { 7946 continue; 7947 } 7948 } else { 7949 tableColumn = tableModel.getColumns().get(i); 7950 } 7951 7952 if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) { 7953 appendTableColumnToSQLEnv(tableModel, tableColumn); 7954 } 7955 7956 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7957 relation.setEffectType(EffectType.create_table); 7958 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7959 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7960 Process process = modelFactory.createProcess(stmt); 7961 relation.setProcess(process); 7962 } else if (columnObject.getFieldAttr() != null || (columnObject.getExpr()!=null && columnObject.getExpr().getExpressionType() == EExpressionType.typecast_t)) { 7963 TableColumn tableColumn = null; 7964 TObjectName columnObj = columnObject.getFieldAttr(); 7965 if(columnObj == null) { 7966 columnObj = columnObject.getExpr().getLeftOperand().getObjectOperand(); 7967 } 7968 if (!hasDefinition) { 7969 tableColumn = modelFactory.createTableColumn(tableModel, columnObj, 7970 !hasDefinition); 7971 if (tableColumn == null) { 7972 continue; 7973 } 7974 } else { 7975 tableColumn = tableModel.getColumns().get(i); 7976 } 7977 ResultColumn column = (ResultColumn) modelManager.getModel(resultColumn.getColumnObject()); 7978 if (column != null && !column.getStarLinkColumns().isEmpty()) { 7979 tableColumn.bindStarLinkColumns(column.getStarLinkColumns()); 7980 } 7981 7982 if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) { 7983 appendTableColumnToSQLEnv(tableModel, tableColumn); 7984 } 7985 7986 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 7987 relation.setEffectType(EffectType.create_table); 7988 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 7989 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 7990 Process process = modelFactory.createProcess(stmt); 7991 relation.setProcess(process); 7992 } else { 7993 ErrorInfo errorInfo = new ErrorInfo(); 7994 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 7995 errorInfo.setErrorMessage("Can't handle the table column " + columnObject.toString()); 7996 errorInfo.setStartPosition(new Pair3<Long, Long, String>( 7997 columnObject.getStartToken().lineNo, columnObject.getStartToken().columnNo, 7998 ModelBindingManager.getGlobalHash())); 7999 errorInfo.setEndPosition(new Pair3<Long, Long, String>(columnObject.getEndToken().lineNo, 8000 columnObject.getEndToken().columnNo + columnObject.getEndToken().getAstext().length(), 8001 ModelBindingManager.getGlobalHash())); 8002 errorInfos.add(errorInfo); 8003 continue; 8004 } 8005 } else if (resultColumn.getColumnObject() instanceof TObjectName) { 8006 TableColumn tableColumn = null; 8007 if (!hasDefinition) { 8008 tableColumn = modelFactory.createTableColumn(tableModel, 8009 (TObjectName) resultColumn.getColumnObject(), !hasDefinition); 8010 } else { 8011 tableColumn = tableModel.getColumns().get(i); 8012 } 8013 8014 if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) { 8015 appendTableColumnToSQLEnv(tableModel, tableColumn); 8016 } 8017 8018 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8019 relation.setEffectType(EffectType.create_table); 8020 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 8021 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 8022 Process process = modelFactory.createProcess(stmt); 8023 relation.setProcess(process); 8024 } 8025 } 8026 } else if (stmt.getLikeTableName() != null) { 8027 Table likeTableModel = modelFactory.createTableByName(stmt.getLikeTableName()); 8028 8029 if(likeTableModel.isCreateTable()){ 8030 for(TableColumn column: likeTableModel.getColumns()){ 8031 TObjectName tableColumn = new TObjectName(); 8032 tableColumn.setString(column.getName()); 8033 TableColumn createTableColumn = modelFactory.createTableColumn(tableModel, tableColumn, true); 8034 createTableColumn.setPrimaryKey(column.getPrimaryKey()); 8035 createTableColumn.setForeignKey(column.getForeignKey()); 8036 createTableColumn.setIndexKey(column.getIndexKey()); 8037 createTableColumn.setUnqiueKey(column.getUnqiueKey()); 8038 createTableColumn.setDataType(column.getDataType()); 8039 } 8040 tableModel.setCreateTable(true); 8041 } 8042 8043// Process process = modelFactory.createProcess(stmt); 8044// process.setType("Like Table"); 8045// tableModel.addProcess(process); 8046// 8047// 8048// DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8049// relation.setEffectType(EffectType.like_table); 8050// relation.setTarget( 8051// new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows())); 8052// relation.addSource( 8053// new RelationRowsRelationshipElement<TableRelationRows>(likeTableModel.getRelationRows())); 8054// relation.setProcess(process); 8055 } 8056 8057 if (stmt.getStageLocation() != null && stmt.getStageLocation().getStageName() != null) { 8058 tableModel 8059 .setLocation(DlineageUtil.getTableFullName(stmt.getStageLocation().getStageName().toString())); 8060 Process process = modelFactory.createProcess(stmt); 8061 process.setType("Create External Table"); 8062 tableModel.addProcess(process); 8063 Table stage = modelManager.getTableByName(DlineageUtil.getTableFullName(tableModel.getLocation())); 8064 if (stage == null) { 8065 stage = modelManager.getTableByName( 8066 DlineageUtil.getTableFullName(stmt.getStageLocation().toString().replaceFirst("@", ""))); 8067 } 8068 if (stage == null) { 8069 stage = modelFactory.createTableByName(stmt.getStageLocation().toString().replaceFirst("@", ""), 8070 false); 8071 stage.setCreateTable(false); 8072 stage.setStage(true); 8073 if (stmt.getStageLocation().getPath() != null) { 8074 stage.setLocation(stmt.getStageLocation().getPath().toString()); 8075 TObjectName location = new TObjectName(); 8076 location.setString(stmt.getStageLocation().getPath().toString()); 8077 modelFactory.createStageLocation(stage, location); 8078 } else if (stmt.getRegex_pattern() != null) { 8079 stage.setLocation(stmt.getRegex_pattern()); 8080 TObjectName location = new TObjectName(); 8081 location.setString(stmt.getRegex_pattern()); 8082 modelFactory.createStageLocation(stage, location); 8083 } else { 8084 stage.setLocation("unknownPath"); 8085 TObjectName location = new TObjectName(); 8086 location.setString("unknownPath"); 8087 modelFactory.createStageLocation(stage, location); 8088 } 8089 } 8090 if (stage != null && !stage.getColumns().isEmpty()) { 8091 if (!tableModel.getColumns().isEmpty()) { 8092 for (int i = 0; i < tableModel.getColumns().size(); i++) { 8093 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8094 relation.addSource(new TableColumnRelationshipElement(stage.getColumns().get(0))); 8095 relation.setTarget(new TableColumnRelationshipElement(tableModel.getColumns().get(i))); 8096 relation.setProcess(process); 8097 } 8098 } else { 8099 TObjectName starColumn = new TObjectName(); 8100 starColumn.setString("*"); 8101 TableColumn tableColumn = modelFactory.createTableColumn(tableModel, starColumn, true); 8102 tableColumn.setExpandStar(false); 8103 tableColumn.setShowStar(true); 8104 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8105 relation.addSource(new TableColumnRelationshipElement(stage.getColumns().get(0))); 8106 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 8107 relation.setProcess(process); 8108 } 8109 } 8110 } else if (stmt.getTableOptions() != null && !stmt.getTableOptions().isEmpty()) { 8111 for (int i = 0; i < stmt.getTableOptions().size(); i++) { 8112 TCreateTableOption createTableOption = stmt.getTableOptions().get(i); 8113 if (createTableOption.getCreateTableOptionType() != ECreateTableOption.etoBigQueryExternal) 8114 continue; 8115 List<String> uris = createTableOption.getUris(); 8116 if (uris == null || uris.isEmpty()) 8117 continue; 8118 Process process = modelFactory.createProcess(stmt); 8119 process.setType("Create External Table"); 8120 tableModel.addProcess(process); 8121 if (tableModel.getColumns().isEmpty()) { 8122 TObjectName starColumn = new TObjectName(); 8123 starColumn.setString("*"); 8124 TableColumn tableColumn = modelFactory.createTableColumn(tableModel, starColumn, true); 8125 tableColumn.setExpandStar(false); 8126 tableColumn.setShowStar(true); 8127 } 8128 for (String uri : uris) { 8129 Table uriFile = modelFactory.createTableByName(uri, true); 8130 uriFile.setPath(true); 8131 uriFile.setFileFormat(createTableOption.getFormat()); 8132 for (int j = 0; j < tableModel.getColumns().size(); j++) { 8133 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8134 if (stmt.getColumnList() != null) { 8135 TObjectName fileUri = new TObjectName(); 8136 fileUri.setString(tableModel.getColumns().get(j).getColumnObject().toString()); 8137 TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri); 8138 relation.addSource(new TableColumnRelationshipElement(fileUriColumn)); 8139 } else { 8140 TObjectName fileUri = new TObjectName(); 8141 fileUri.setString("*"); 8142 TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri); 8143 relation.addSource(new TableColumnRelationshipElement(fileUriColumn)); 8144 } 8145 relation.setTarget(new TableColumnRelationshipElement(tableModel.getColumns().get(j))); 8146 relation.setProcess(process); 8147 } 8148 if (tableModel.getColumns().isEmpty()) { 8149 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8150 TObjectName fileUri = new TObjectName(); 8151 fileUri.setString("*"); 8152 TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri); 8153 relation.addSource(new TableColumnRelationshipElement(fileUriColumn)); 8154 relation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>( 8155 tableModel.getRelationRows())); 8156 relation.setProcess(process); 8157 } 8158 } 8159 } 8160 } else if (stmt.getSubQuery() == null && stmt.getTableLocation() != null) { 8161 Process process = modelFactory.createProcess(stmt); 8162 process.setType("Create External Table"); 8163 tableModel.addProcess(process); 8164 Table uriFile = modelFactory.createTableByName(stmt.getTableLocation(), true); 8165 uriFile.setPath(true); 8166 for (int j = 0; j < tableModel.getColumns().size(); j++) { 8167 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8168 if (stmt.getColumnList() != null) { 8169 TObjectName fileUri = new TObjectName(); 8170 fileUri.setString(tableModel.getColumns().get(j).getColumnObject().toString()); 8171 TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri); 8172 relation.addSource(new TableColumnRelationshipElement(fileUriColumn)); 8173 } else { 8174 TObjectName fileUri = new TObjectName(); 8175 fileUri.setString("*"); 8176 TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri); 8177 relation.addSource(new TableColumnRelationshipElement(fileUriColumn)); 8178 } 8179 relation.setTarget(new TableColumnRelationshipElement(tableModel.getColumns().get(j))); 8180 relation.setProcess(process); 8181 } 8182 } 8183 8184 // Inline (column-level) FK relationships. Emitted here, after the 8185 // column loop, rather than inline in it, so the referenced-column / 8186 // relation / process model objects allocate their ids AFTER all 8187 // column ids (matching the table-level pass below) and column ids 8188 // stay stable. Mirrors the table-level FK emission: source = 8189 // referenced column, target = this FK column, effect = foreign_key, 8190 // plus the optional ER relationship. EConstraintType.reference is 8191 // the inline REFERENCES form; foreign_key the inline FOREIGN KEY. 8192 if (stmt.getColumnList() != null) { 8193 for (int i = 0; i < stmt.getColumnList().size(); i++) { 8194 TColumnDefinition fkColumnDef = stmt.getColumnList().getColumn(i); 8195 TConstraintList fkConstraints = fkColumnDef.getConstraints(); 8196 if (fkConstraints == null) { 8197 continue; 8198 } 8199 for (int c = 0; c < fkConstraints.size(); c++) { 8200 TConstraint inlineConstraint = fkConstraints.getConstraint(c); 8201 EConstraintType inlineType = inlineConstraint.getConstraint_type(); 8202 if (inlineType != EConstraintType.foreign_key 8203 && inlineType != EConstraintType.reference) { 8204 continue; 8205 } 8206 TObjectName referencedTableName = inlineConstraint.getReferencedObject(); 8207 TObjectNameList referencedTableColumns = inlineConstraint.getReferencedColumnList(); 8208 if (referencedTableName == null || referencedTableColumns == null) { 8209 continue; 8210 } 8211 TableColumn fkColumn = modelFactory.createTableColumn(tableModel, 8212 fkColumnDef.getColumnName(), true); 8213 if (fkColumn == null) { 8214 continue; 8215 } 8216 Table referencedTable = modelManager.getTableByName( 8217 DlineageUtil.getTableFullName(referencedTableName.toString())); 8218 if (referencedTable == null) { 8219 referencedTable = modelFactory.createTableByName(referencedTableName); 8220 } 8221 for (int j = 0; j < referencedTableColumns.size(); j++) { 8222 TableColumn referencedColumn = modelFactory.createTableColumn(referencedTable, 8223 referencedTableColumns.getObjectName(j), false); 8224 if (referencedColumn != null) { 8225 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8226 relation.addSource(new TableColumnRelationshipElement(referencedColumn)); 8227 relation.setTarget(new TableColumnRelationshipElement(fkColumn)); 8228 relation.setEffectType(EffectType.foreign_key); 8229 Process process = modelFactory.createProcess(stmt); 8230 relation.setProcess(process); 8231 if (this.option.isShowERDiagram()) { 8232 ERRelationship erRelation = modelFactory.createERRelation(); 8233 erRelation.addSource(new TableColumnRelationshipElement(referencedColumn)); 8234 erRelation.setTarget(new TableColumnRelationshipElement(fkColumn)); 8235 } 8236 } 8237 } 8238 } 8239 } 8240 } 8241 8242 if (stmt.getTableConstraints() != null && stmt.getTableConstraints().size() > 0) { 8243 for (int i = 0; i < stmt.getTableConstraints().size(); i++) { 8244 TConstraint createTableConstraint = stmt.getTableConstraints().getConstraint(i); 8245 TPTNodeList<TColumnWithSortOrder> keyNames = createTableConstraint.getColumnList(); 8246 if (keyNames != null) { 8247 for (int k = 0; k < keyNames.size(); k++) { 8248 TObjectName keyName = keyNames.getElement(k).getColumnName(); 8249 // Skip functional indexes (expression-based indexes) where columnName is null 8250 if (keyName == null) { 8251 continue; 8252 } 8253 TObjectName referencedTableName = createTableConstraint.getReferencedObject(); 8254 TObjectNameList referencedTableColumns = createTableConstraint.getReferencedColumnList(); 8255 8256 TableColumn tableConstraint = modelFactory.createTableColumn(tableModel, keyName, true); 8257 if (createTableConstraint.getConstraint_type() == EConstraintType.primary_key) { 8258 tableConstraint.setPrimaryKey(true); 8259 } else if (createTableConstraint.getConstraint_type() == EConstraintType.table_index) { 8260 tableConstraint.setIndexKey(true); 8261 } else if (createTableConstraint.getConstraint_type() == EConstraintType.unique) { 8262 tableConstraint.setUnqiueKey(true); 8263 } else if (createTableConstraint.getConstraint_type() == EConstraintType.foreign_key) { 8264 tableConstraint.setForeignKey(true); 8265 Table referencedTable = modelManager 8266 .getTableByName(DlineageUtil.getTableFullName(referencedTableName.toString())); 8267 if (referencedTable == null) { 8268 referencedTable = modelFactory.createTableByName(referencedTableName); 8269 } 8270 8271 if (referencedTableColumns != null) { 8272 for (int j = 0; j < referencedTableColumns.size(); j++) { 8273 TableColumn tableColumn = modelFactory.createTableColumn(referencedTable, 8274 referencedTableColumns.getObjectName(j), false); 8275 if (tableColumn != null) { 8276 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8277 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 8278 relation.setTarget(new TableColumnRelationshipElement(tableConstraint)); 8279 relation.setEffectType(EffectType.foreign_key); 8280 Process process = modelFactory.createProcess(stmt); 8281 relation.setProcess(process); 8282 if (this.option.isShowERDiagram()) { 8283 ERRelationship erRelation = modelFactory.createERRelation(); 8284 erRelation.addSource(new TableColumnRelationshipElement(tableColumn)); 8285 erRelation 8286 .setTarget(new TableColumnRelationshipElement(tableConstraint)); 8287 } 8288 } 8289 } 8290 } 8291 } 8292 } 8293 } 8294 } 8295 } 8296 8297 if (stmt.getHiveTablePartition() != null && stmt.getHiveTablePartition().getColumnDefList() != null) { 8298 for (int i = 0; i < stmt.getHiveTablePartition().getColumnDefList().size(); i++) { 8299 TColumnDefinition column = stmt.getHiveTablePartition().getColumnDefList().getColumn(i); 8300 modelFactory.createTableColumn(tableModel, column.getColumnName(), true); 8301 appendTableColumnToSQLEnv(tableModel, column.getColumnName()); 8302 } 8303 } 8304 8305 } else { 8306 ErrorInfo errorInfo = new ErrorInfo(); 8307 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 8308 errorInfo.setErrorMessage("Can't get target table. CreateTableSqlStatement is " + stmt.toString()); 8309 errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo, 8310 stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash())); 8311 errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo, 8312 stmt.getEndToken().columnNo + stmt.getEndToken().getAstext().length(), 8313 ModelBindingManager.getGlobalHash())); 8314 errorInfos.add(errorInfo); 8315 } 8316 } 8317 8318 protected void flattenStructColumns(boolean hasDefinition, Table tableModel, TColumnDefinition column, 8319 Stack<TColumnDefinition> columnPaths, int index) { 8320 columnPaths.push(column); 8321 for (int j = 0; j < column.getDatatype().getColumnDefList().size(); j++) { 8322 TColumnDefinition columnDefinition = column.getDatatype().getColumnDefList().getColumn(j); 8323 if (columnDefinition.getDatatype().getColumnDefList() != null) { 8324 flattenStructColumns(hasDefinition, tableModel, columnDefinition, columnPaths, index); 8325 } else { 8326 TObjectName columnName = new TObjectName(); 8327 columnName.setString(getColumnName(columnPaths, columnDefinition)); 8328 TableColumn tableColumn = modelFactory.createTableColumn(tableModel, columnName, hasDefinition); 8329 tableColumn.setColumnIndex(index); 8330 tableColumn.setStruct(true); 8331 8332 if(option.getAnalyzeMode() == AnalyzeMode.crud) { 8333 CrudRelationship crudRelationship = modelFactory.createCrudRelation(); 8334 crudRelationship.setTarget(new TableColumnRelationshipElement(tableColumn)); 8335 crudRelationship.setEffectType(EffectType.create_table); 8336 } 8337 8338 appendTableColumnToSQLEnv(tableModel, tableColumn); 8339 } 8340 } 8341 columnPaths.pop(); 8342 } 8343 8344 private String getColumnName(Stack<TColumnDefinition> columnPaths, TColumnDefinition column) { 8345 StringBuilder buffer = new StringBuilder(); 8346 Iterator<TColumnDefinition> iter = columnPaths.iterator(); 8347 while(iter.hasNext()) { 8348 buffer.append(iter.next().getColumnName().getColumnNameOnly()).append("."); 8349 } 8350 buffer.append(column.getColumnName().getColumnNameOnly()); 8351 return buffer.toString(); 8352 } 8353 8354 private void appendTableColumnToSQLEnv(Table tableModel, TableColumn tableColumn) { 8355 //tableModel如果非determined,请不要添加到sqlenv里 8356 if (sqlenv != null && tableColumn!=null) { 8357 TSQLSchema schema = sqlenv.getSQLSchema(DlineageUtil.getTableSchema(tableModel), true); 8358 if (schema != null) { 8359 TSQLTable tempTable = schema.createTable(DlineageUtil.getSimpleTableName(tableModel.getName())); 8360 if (tableColumn.hasStarLinkColumn()) { 8361 for (String column : tableColumn.getStarLinkColumnNames()) { 8362 tempTable.addColumn(DlineageUtil.getColumnNameOnly(column)); 8363 } 8364 } else { 8365 tempTable.addColumn(DlineageUtil.getColumnNameOnly(tableColumn.getName())); 8366 } 8367 } 8368 } 8369 } 8370 8371 private void appendTableColumnToSQLEnv(Table tableModel, TObjectName tableColumn) { 8372 if (sqlenv != null) { 8373 TSQLSchema schema = sqlenv.getSQLSchema(DlineageUtil.getTableSchema(tableModel), true); 8374 if (schema != null) { 8375 TSQLTable tempTable = schema.createTable(DlineageUtil.getSimpleTableName(tableModel.getName())); 8376 tempTable.addColumn(DlineageUtil.getColumnNameOnly(tableColumn.getColumnNameOnly())); 8377 } 8378 } 8379 } 8380 8381 private void analyzeCreateStageStmt(TCreateStageStmt stmt) { 8382 TObjectName stageName = stmt.getStageName(); 8383 8384 if (stageName != null) { 8385 8386 Table tableModel = modelFactory.createStage(stageName); 8387 tableModel.setCreateTable(true); 8388 tableModel.setStage(true); 8389 tableModel.setLocation(stmt.getExternalStageURL()); 8390 8391 Process process = modelFactory.createProcess(stmt); 8392 tableModel.addProcess(process); 8393 8394 TableColumn locationColumn = null; 8395 if (stmt.getExternalStageURL() != null) { 8396 TObjectName location = new TObjectName(); 8397 location.setString(stmt.getExternalStageURL()); 8398 locationColumn = modelFactory.createStageLocation(tableModel, location); 8399 8400 Table pathModel = modelFactory.createTableByName(stmt.getExternalStageURL(), true); 8401 pathModel.setPath(true); 8402 pathModel.setCreateTable(true); 8403 TObjectName fileUri = new TObjectName(); 8404 fileUri.setString(stmt.getExternalStageURL()); 8405 TableColumn fileUriColumn = modelFactory.createFileUri(pathModel, fileUri); 8406 8407 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8408 relation.addSource(new TableColumnRelationshipElement(fileUriColumn)); 8409 relation.setTarget(new TableColumnRelationshipElement(locationColumn)); 8410 relation.setProcess(process); 8411 8412 } else { 8413 for (TCustomSqlStatement temp : stmt.getGsqlparser().getSqlstatements()) { 8414 if (temp instanceof TPutStmt) { 8415 TPutStmt put = (TPutStmt) temp; 8416 TStageLocation stageLocation = put.getStageLocation(); 8417 if (stageLocation != null && stageLocation.getStageName() != null) { 8418 Table stage = modelManager.getTableByName( 8419 DlineageUtil.getTableFullName(stageLocation.getStageName().toString())); 8420 if (stage == tableModel) { 8421 TObjectName location = new TObjectName(); 8422 if (!SQLUtil.isEmpty(put.getFileName())) { 8423 location.setString(put.getFileName()); 8424 locationColumn = modelFactory.createStageLocation(tableModel, location); 8425 } 8426 break; 8427 } 8428 } 8429 } 8430 } 8431 } 8432 8433 String fileFormat = stmt.getFileFormatName(); 8434 if (fileFormat != null) { 8435 for (TCustomSqlStatement temp : stmt.getGsqlparser().getSqlstatements()) { 8436 if (temp instanceof TCreateFileFormatStmt) { 8437 TCreateFileFormatStmt fileFormatStmt = (TCreateFileFormatStmt) temp; 8438 if (fileFormatStmt.getFileFormatName() != null 8439 && fileFormatStmt.getFileFormatName().toString().equalsIgnoreCase(fileFormat)) { 8440 tableModel.setFileType(fileFormatStmt.getTypeName()); 8441 break; 8442 } 8443 } 8444 } 8445 } 8446 8447 String procedureParent = getProcedureParentName(stmt); 8448 if (procedureParent != null) { 8449 tableModel.setParent(procedureParent); 8450 } 8451 8452 if (locationColumn != null) { 8453 List<Table> tables = modelManager.getTablesByName(); 8454 if (tables != null) { 8455 for (Table referTable : tables) { 8456 if (referTable.getLocation() != null && referTable.getLocation() 8457 .equals(DlineageUtil.getIdentifierNormalTableName(tableModel.getName()))) { 8458 for (int i = 0; i < referTable.getColumns().size(); i++) { 8459 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8460 relation.addSource(new TableColumnRelationshipElement(locationColumn)); 8461 relation.setTarget(new TableColumnRelationshipElement(referTable.getColumns().get(i))); 8462 } 8463 } 8464 } 8465 } 8466 } 8467 } else { 8468 ErrorInfo errorInfo = new ErrorInfo(); 8469 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 8470 errorInfo.setErrorMessage("Can't get target table. CreateStageStmt is " + stmt.toString()); 8471 errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo, 8472 stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash())); 8473 errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo, 8474 stmt.getEndToken().columnNo + stmt.getEndToken().getAstext().length(), 8475 ModelBindingManager.getGlobalHash())); 8476 errorInfo.fillInfo(this); 8477 errorInfos.add(errorInfo); 8478 } 8479 } 8480 8481 private void analyzeCreateExternalDataSourceStmt(TCreateExternalDataSourceStmt stmt) { 8482 TObjectName dataSourceName = stmt.getDataSourceName(); 8483 String locationUrl = stmt.getOption("LOCATION"); 8484 if (dataSourceName != null && locationUrl != null) { 8485 Table tableModel = modelFactory.createDataSource(dataSourceName); 8486 tableModel.setCreateTable(true); 8487 tableModel.setDataSource(true); 8488 tableModel.setLocation(locationUrl); 8489 8490 Process process = modelFactory.createProcess(stmt); 8491 tableModel.addProcess(process); 8492 8493 TObjectName location = new TObjectName(); 8494 location.setString(locationUrl); 8495 modelFactory.createTableColumn(tableModel, location, true); 8496 8497 String procedureParent = getProcedureParentName(stmt); 8498 if (procedureParent != null) { 8499 tableModel.setParent(procedureParent); 8500 } 8501 } else { 8502 ErrorInfo errorInfo = new ErrorInfo(); 8503 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 8504 errorInfo.setErrorMessage("Can't get target table. CreateExternalDataSourceStmt is " + stmt.toString()); 8505 errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo, 8506 stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash())); 8507 errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo, 8508 stmt.getEndToken().columnNo + stmt.getEndToken().getAstext().length(), 8509 ModelBindingManager.getGlobalHash())); 8510 errorInfo.fillInfo(this); 8511 errorInfos.add(errorInfo); 8512 } 8513 } 8514 8515 private void analyzeCreateStreamStmt(TCreateStreamStmt stmt) { 8516 TObjectName streamName = stmt.getStreamName(); 8517 8518 if (streamName != null) { 8519 Table tableModel = modelFactory.createTableByName(stmt.getTableName()); 8520 tableModel.setCreateTable(true); 8521 8522 Table streamModel = modelFactory.createStream(streamName); 8523 streamModel.setCreateTable(true); 8524 streamModel.setStream(true); 8525 8526 Process process = modelFactory.createProcess(stmt); 8527 tableModel.addProcess(process); 8528 8529 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8530 relation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(streamModel.getRelationRows())); 8531 relation.addSource(new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows())); 8532 relation.setProcess(process); 8533 } 8534 } 8535 8536 private String getProcedureParentName(TCustomSqlStatement stmt) { 8537 if (stmt instanceof TStoredProcedureSqlStatement) { 8538 if (((TStoredProcedureSqlStatement) stmt).getStoredProcedureName() != null) { 8539 return ((TStoredProcedureSqlStatement) stmt).getStoredProcedureName().toString(); 8540 } 8541 } 8542 8543 stmt = stmt.getParentStmt(); 8544 if (stmt == null) 8545 return null; 8546 8547 if (stmt instanceof TCommonBlock) { 8548 if(((TCommonBlock) stmt).getBlockBody().getParentObjectName() instanceof TStoredProcedureSqlStatement) { 8549 stmt = (TStoredProcedureSqlStatement)((TCommonBlock) stmt).getBlockBody().getParentObjectName(); 8550 } 8551 } 8552 8553 if (stmt instanceof TStoredProcedureSqlStatement) { 8554 if (((TStoredProcedureSqlStatement) stmt).getStoredProcedureName() != null) { 8555 return ((TStoredProcedureSqlStatement) stmt).getStoredProcedureName().toString(); 8556 } 8557 } 8558 if (stmt instanceof TTeradataCreateProcedure) { 8559 if (((TTeradataCreateProcedure) stmt).getProcedureName() != null) { 8560 return ((TTeradataCreateProcedure) stmt).getProcedureName().toString(); 8561 } 8562 } 8563 8564 return getProcedureParentName(stmt); 8565 } 8566 8567 private TStoredProcedureSqlStatement getProcedureParent(TCustomSqlStatement stmt) { 8568 if (stmt instanceof TStoredProcedureSqlStatement) { 8569 return (TStoredProcedureSqlStatement) stmt; 8570 } 8571 8572 stmt = stmt.getParentStmt(); 8573 if (stmt == null) 8574 return null; 8575 8576 if (stmt instanceof TCommonBlock) { 8577 if (((TCommonBlock) stmt).getBlockBody().getParentObjectName() instanceof TStoredProcedureSqlStatement) { 8578 stmt = (TStoredProcedureSqlStatement) ((TCommonBlock) stmt).getBlockBody().getParentObjectName(); 8579 } 8580 } 8581 8582 if (stmt instanceof TStoredProcedureSqlStatement) { 8583 return ((TStoredProcedureSqlStatement) stmt); 8584 } 8585 if (stmt instanceof TTeradataCreateProcedure) { 8586 return ((TTeradataCreateProcedure) stmt); 8587 } 8588 8589 return getProcedureParent(stmt); 8590 } 8591 8592 private void analyzeMergeStmt(TMergeSqlStatement stmt) { 8593 Object tableModel; 8594 Process process; 8595 if (stmt.getUsingTable() != null) { 8596 TTable table = stmt.getTargetTable(); 8597 if(table.getSubquery()!=null) { 8598 tableModel = modelFactory.createQueryTable(table); 8599 analyzeSelectStmt(table.getSubquery()); 8600 process = modelFactory.createProcess(stmt); 8601 } 8602 else { 8603 tableModel = modelFactory.createTable(table); 8604 process = modelFactory.createProcess(stmt); 8605 ((Table)tableModel).addProcess(process); 8606 } 8607 8608 for(TTable item: stmt.tables) { 8609 // Skip subqueries and CTE references: a CTE feeding USING is resolved 8610 // through its subquery (see the getCTE() branch below), so materializing 8611 // it here as a physical base table leaves a spurious table named after 8612 // the CTE in the lineage output. (MantisBT #4493) 8613 if(item.getSubquery()!=null || item.getCTE()!=null) { 8614 continue; 8615 } 8616 Table tableItemModel = modelFactory.createTable(item); 8617 if (tableItemModel.getColumns() == null || tableItemModel.getColumns().isEmpty()) { 8618 tableItemModel.addColumnsFromSQLEnv(); 8619 } 8620 } 8621 8622 if (stmt.getUsingTable().getSubquery() != null) { 8623 QueryTable queryTable = modelFactory.createQueryTable(stmt.getUsingTable()); 8624 analyzeSelectStmt(stmt.getUsingTable().getSubquery()); 8625 8626 ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getUsingTable().getSubquery()); 8627 8628 if (queryTable != null && resultSetModel != null && queryTable != resultSetModel) { 8629 if (queryTable.getColumns().size() == resultSetModel.getColumns().size()) { 8630 for (int i = 0; i < queryTable.getColumns().size(); i++) { 8631 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8632 relation.setEffectType(EffectType.select); 8633 relation.setTarget(new ResultColumnRelationshipElement(queryTable.getColumns().get(i))); 8634 relation.addSource(new ResultColumnRelationshipElement(resultSetModel.getColumns().get(i))); 8635 relation.setProcess(process); 8636 } 8637 } 8638 } 8639 8640 if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 8641 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 8642 impactRelation.setEffectType(EffectType.merge); 8643 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 8644 resultSetModel.getRelationRows())); 8645 if (tableModel instanceof Table) { 8646 impactRelation.setTarget( 8647 new RelationRowsRelationshipElement<TableRelationRows>(((Table)tableModel).getRelationRows())); 8648 } 8649 else { 8650 impactRelation.setTarget( 8651 new RelationRowsRelationshipElement<ResultSetRelationRows>(((ResultSet)tableModel).getRelationRows())); 8652 } 8653 } 8654 } else if (stmt.getUsingTable().getCTE() != null) { 8655 // USING references a CTE defined in the WITH clause attached to the 8656 // MERGE. Mirror the SELECT-side CTE handling so the CTE subquery (and 8657 // the base tables inside it) are analyzed and linked through to the 8658 // merge source; otherwise the CTE is treated as an opaque base table 8659 // and the tables feeding it are dropped from the lineage. (MantisBT #4493) 8660 QueryTable queryTable = modelFactory.createQueryTable(stmt.getUsingTable()); 8661 8662 TObjectNameList cteColumns = stmt.getUsingTable().getCTE().getColumnList(); 8663 if (cteColumns != null) { 8664 for (int j = 0; j < cteColumns.size(); j++) { 8665 modelFactory.createResultColumn(queryTable, cteColumns.getObjectName(j)); 8666 } 8667 } 8668 8669 TSelectSqlStatement subquery = stmt.getUsingTable().getCTE().getSubquery(); 8670 if (subquery != null && !stmtStack.contains(subquery)) { 8671 analyzeSelectStmt(subquery); 8672 8673 ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery); 8674 8675 if (resultSetModel != null && resultSetModel != queryTable) { 8676 if (subquery.getSetOperatorType() != ESetOperatorType.none) { 8677 SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager 8678 .getModel(subquery); 8679 for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) { 8680 ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j); 8681 ResultColumn targetColumn = null; 8682 if (cteColumns != null && j < queryTable.getColumns().size()) { 8683 targetColumn = queryTable.getColumns().get(j); 8684 } else { 8685 targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn); 8686 } 8687 for (Set<TObjectName> starLinkColumns : sourceColumn.getStarLinkColumns().values()) { 8688 for (TObjectName starLinkColumn : starLinkColumns) { 8689 targetColumn.bindStarLinkColumn(starLinkColumn); 8690 } 8691 } 8692 DataFlowRelationship cteRelation = modelFactory.createDataFlowRelation(); 8693 cteRelation.setEffectType(EffectType.select); 8694 cteRelation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 8695 cteRelation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 8696 cteRelation.setProcess(process); 8697 } 8698 } else { 8699 for (int j = 0; j < resultSetModel.getColumns().size(); j++) { 8700 ResultColumn sourceColumn = resultSetModel.getColumns().get(j); 8701 ResultColumn targetColumn = null; 8702 if (cteColumns != null && j < queryTable.getColumns().size()) { 8703 targetColumn = queryTable.getColumns().get(j); 8704 } else { 8705 targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn); 8706 } 8707 for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) { 8708 targetColumn.bindStarLinkColumn(starLinkColumn); 8709 } 8710 DataFlowRelationship cteRelation = modelFactory.createDataFlowRelation(); 8711 cteRelation.setEffectType(EffectType.select); 8712 cteRelation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 8713 cteRelation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 8714 cteRelation.setProcess(process); 8715 } 8716 } 8717 } 8718 8719 if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 8720 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 8721 impactRelation.setEffectType(EffectType.merge); 8722 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 8723 resultSetModel.getRelationRows())); 8724 if (tableModel instanceof Table) { 8725 impactRelation.setTarget( 8726 new RelationRowsRelationshipElement<TableRelationRows>(((Table) tableModel).getRelationRows())); 8727 } else { 8728 impactRelation.setTarget( 8729 new RelationRowsRelationshipElement<ResultSetRelationRows>(((ResultSet) tableModel).getRelationRows())); 8730 } 8731 } 8732 } 8733 } else { 8734 if (stmt.getUsingTable().getAliasClause() != null && stmt.getUsingTable().getAliasClause().getColumns() != null && stmt.getUsingTable().getValueClause().getRows()!=null) { 8735 Table usingTable = modelFactory.createTableFromCreateDDL(stmt.getUsingTable(), false, stmt.getUsingTable().getAliasName() + stmt.getUsingTable().getTableName()); 8736 usingTable.setCreateTable(true); 8737 usingTable.setSubType(SubType.function); 8738 for (int z=0;z<stmt.getUsingTable().getAliasClause().getColumns().size();z++) { 8739 TObjectName columnName = stmt.getUsingTable().getAliasClause().getColumns().getObjectName(z); 8740 TableColumn tableColumn = modelFactory.createTableColumn(usingTable, columnName, true); 8741 TResultColumn resultColumn = stmt.getUsingTable().getValueClause().getRows().get(0).getResultColumn(z); 8742 modelManager.bindModel(resultColumn, tableColumn); 8743 analyzeResultColumnExpressionRelation(tableColumn, resultColumn.getExpr()); } 8744 } 8745 else { 8746 modelFactory.createTable(stmt.getUsingTable()); 8747 } 8748 } 8749 8750 8751 if (stmt.getWhenClauses() != null && stmt.getWhenClauses().size() > 0) { 8752 for (int i = 0; i < stmt.getWhenClauses().size(); i++) { 8753 TMergeWhenClause clause = stmt.getWhenClauses().getElement(i); 8754 if (clause.getCondition() != null) { 8755 analyzeFilterCondition(null, clause.getCondition(), null, null, EffectType.merge_when); 8756 } 8757 if (clause.getUpdateClause() != null) { 8758 TResultColumnList columns = clause.getUpdateClause().getUpdateColumnList(); 8759 if (columns == null || columns.size() == 0) 8760 continue; 8761 8762 ResultSet resultSet = modelFactory.createResultSet(clause.getUpdateClause(), false); 8763 createPseudoImpactRelation(stmt, resultSet, EffectType.merge_update); 8764 8765 for (int j = 0; j < columns.size(); j++) { 8766 TResultColumn resultColumn = columns.getResultColumn(j); 8767 if (resultColumn.getExpr().getLeftOperand() 8768 .getExpressionType() == EExpressionType.simple_object_name_t) { 8769 TObjectName columnObject = resultColumn.getExpr().getLeftOperand().getObjectOperand(); 8770 8771 if (columnObject.getDbObjectType() == EDbObjectType.variable) { 8772 continue; 8773 } 8774 8775 if (columnObject.getColumnNameOnly().startsWith("@") 8776 && (option.getVendor() == EDbVendor.dbvmssql 8777 || option.getVendor() == EDbVendor.dbvazuresql)) { 8778 continue; 8779 } 8780 8781 if (columnObject.getColumnNameOnly().startsWith(":") 8782 && (option.getVendor() == EDbVendor.dbvhana 8783 || option.getVendor() == EDbVendor.dbvteradata)) { 8784 continue; 8785 } 8786 8787 ResultColumn updateColumn = modelFactory.createMergeResultColumn(resultSet, 8788 columnObject); 8789 8790 TExpression valueExpression = resultColumn.getExpr().getRightOperand(); 8791 if (valueExpression == null) 8792 continue; 8793 8794 columnsInExpr visitor = new columnsInExpr(); 8795 valueExpression.inOrderTraverse(visitor); 8796 List<TObjectName> objectNames = visitor.getObjectNames(); 8797 List<TParseTreeNode> functions = visitor.getFunctions(); 8798 8799 if (functions != null && !functions.isEmpty()) { 8800 analyzeFunctionDataFlowRelation(updateColumn, functions, EffectType.merge_update); 8801 } 8802 8803 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 8804 if (subquerys != null && !subquerys.isEmpty()) { 8805 analyzeSubqueryDataFlowRelation(updateColumn, subquerys, EffectType.merge_update); 8806 } 8807 8808 analyzeDataFlowRelation(updateColumn, objectNames, EffectType.merge_update, functions); 8809 8810 List<TParseTreeNode> constants = visitor.getConstants(); 8811 analyzeConstantDataFlowRelation(updateColumn, constants, EffectType.merge_update, 8812 functions); 8813 8814 if (tableModel instanceof Table) { 8815 TableColumn tableColumn = modelFactory.createTableColumn((Table)tableModel, columnObject, 8816 false); 8817 8818 if (tableColumn != null) { 8819 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8820 relation.setEffectType(EffectType.merge_update); 8821 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 8822 relation.addSource(new ResultColumnRelationshipElement(updateColumn)); 8823 relation.setProcess(process); 8824 } 8825 } 8826 else { 8827 TTable targetTable = stmt.getTargetTable().getSubquery().getTables().getTable(0); 8828 if (targetTable != null && modelManager.getModel(targetTable) instanceof Table) { 8829 Table targetTableModel = (Table) modelManager.getModel(targetTable); 8830 TableColumn tableColumn = modelFactory 8831 .createTableColumn((Table) targetTableModel, columnObject, false); 8832 if (tableColumn != null) { 8833 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8834 relation.setEffectType(EffectType.merge_update); 8835 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 8836 relation.addSource(new ResultColumnRelationshipElement(updateColumn)); 8837 relation.setProcess(process); 8838 } 8839 } 8840 } 8841 } 8842 } 8843 } 8844 if (clause.getInsertClause() != null && tableModel instanceof Table) { 8845 TExpression insertValue = clause.getInsertClause().getInsertValue(); 8846 if (insertValue != null 8847 && insertValue.getExpressionType() == EExpressionType.objectConstruct_t) { 8848 ResultSet resultSet = modelFactory.createResultSet(clause.getInsertClause(), false); 8849 8850 createPseudoImpactRelation(stmt, resultSet, EffectType.merge_insert); 8851 8852 TObjectConstruct objectConstruct = insertValue.getObjectConstruct(); 8853 for (int z = 0; z < objectConstruct.getPairs().size(); z++) { 8854 TPair pair = objectConstruct.getPairs().getElement(z); 8855 8856 if (pair.getKeyName().getExpressionType() == EExpressionType.simple_constant_t) { 8857 TObjectName columnObject = new TObjectName(); 8858 TConstant constant = pair.getKeyName().getConstantOperand(); 8859 TSourceToken newSt = new TSourceToken( 8860 constant.getValueToken().getTextWithoutQuoted()); 8861 columnObject.setPartToken(newSt); 8862 columnObject.setSourceTable(stmt.getTargetTable()); 8863 columnObject.setStartToken(constant.getStartToken()); 8864 columnObject.setEndToken(constant.getEndToken()); 8865 8866 ResultColumn insertColumn = modelFactory.createMergeResultColumn(resultSet, 8867 columnObject); 8868 8869 TExpression valueExpression = pair.getKeyValue(); 8870 if (valueExpression == null) 8871 continue; 8872 8873 columnsInExpr visitor = new columnsInExpr(); 8874 valueExpression.inOrderTraverse(visitor); 8875 List<TObjectName> objectNames = visitor.getObjectNames(); 8876 List<TParseTreeNode> functions = visitor.getFunctions(); 8877 8878 if (functions != null && !functions.isEmpty()) { 8879 analyzeFunctionDataFlowRelation(insertColumn, functions, 8880 EffectType.merge_insert); 8881 } 8882 8883 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 8884 if (subquerys != null && !subquerys.isEmpty()) { 8885 analyzeSubqueryDataFlowRelation(insertColumn, subquerys, 8886 EffectType.merge_insert); 8887 } 8888 8889 analyzeDataFlowRelation(insertColumn, objectNames, EffectType.merge_insert, 8890 functions); 8891 8892 List<TParseTreeNode> constants = visitor.getConstants(); 8893 analyzeConstantDataFlowRelation(insertColumn, constants, EffectType.merge_insert, 8894 functions); 8895 8896 TableColumn tableColumn = modelFactory.createTableColumn((Table)tableModel, 8897 columnObject, false); 8898 8899 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8900 relation.setEffectType(EffectType.merge_insert); 8901 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 8902 relation.addSource(new ResultColumnRelationshipElement(insertColumn)); 8903 relation.setProcess(process); 8904 } 8905 } 8906 } else { 8907 TObjectNameList columns = clause.getInsertClause().getColumnList(); 8908 TResultColumnList values = clause.getInsertClause().getValuelist(); 8909 if (values == null || values.size() == 0) { 8910 if (clause.getInsertClause().toString().toLowerCase().indexOf("row") != -1) { 8911 if (stmt.getUsingTable().getSubquery() != null) { 8912 ResultSet sourceResultSet = modelFactory.createQueryTable(stmt.getUsingTable()); 8913 TObjectName targetStarColumn = new TObjectName(); 8914 targetStarColumn.setString("*"); 8915 TableColumn targetTableColumn = modelFactory.createTableColumn((Table)tableModel, 8916 targetStarColumn, true); 8917 if (sourceResultSet.getColumns() == null 8918 || sourceResultSet.getColumns().isEmpty()) { 8919 TObjectName sourceStarColumn = new TObjectName(); 8920 sourceStarColumn.setString("*"); 8921 modelFactory.createResultColumn(sourceResultSet, sourceStarColumn); 8922 } 8923 for (ResultColumn sourceColumn : sourceResultSet.getColumns()) { 8924 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8925 relation.setEffectType(EffectType.merge_insert); 8926 relation.setTarget(new TableColumnRelationshipElement(targetTableColumn)); 8927 relation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 8928 relation.setProcess(process); 8929 } 8930 } else { 8931 Table sourceTable = modelFactory.createTable(stmt.getUsingTable()); 8932 TObjectName sourceStarColumn = new TObjectName(); 8933 sourceStarColumn.setString("*"); 8934 TableColumn sourceTableColumn = modelFactory.createTableColumn(sourceTable, 8935 sourceStarColumn, true); 8936 TObjectName targetStarColumn = new TObjectName(); 8937 targetStarColumn.setString("*"); 8938 TableColumn targetTableColumn = modelFactory.createTableColumn(((Table)tableModel), 8939 targetStarColumn, true); 8940 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 8941 relation.setEffectType(EffectType.merge_insert); 8942 relation.setTarget(new TableColumnRelationshipElement(targetTableColumn)); 8943 relation.addSource(new TableColumnRelationshipElement(sourceTableColumn)); 8944 relation.setProcess(process); 8945 } 8946 8947 } 8948 continue; 8949 } 8950 8951 List<TObjectName> tableColumns = new ArrayList<TObjectName>(); 8952 if (columns == null || columns.size() == 0) { 8953// if (!((Table)tableModel).getColumns().isEmpty()) { 8954// for (int j = 0; j < ((Table)tableModel).getColumns().size(); j++) { 8955// if (((Table)tableModel).getColumns().get(j).getColumnObject() == null) { 8956// continue; 8957// } 8958// tableColumns.add(((Table)tableModel).getColumns().get(j).getColumnObject()); 8959// } 8960// } else { 8961 for (int j = 0; j < values.size(); j++) { 8962 TResultColumn column = values.getResultColumn(j); 8963 if (column.getAliasClause() != null) { 8964 tableColumns.add(column.getAliasClause().getAliasName()); 8965 } else if (column.getFieldAttr() != null) { 8966 tableColumns.add(column.getFieldAttr()); 8967 } else { 8968 TObjectName columnName = new TObjectName(); 8969 columnName.setString(column.toString()); 8970 tableColumns.add(columnName); 8971 } 8972// } 8973 } 8974 } else { 8975 for (int j = 0; j < columns.size(); j++) { 8976 tableColumns.add(columns.getObjectName(j)); 8977 } 8978 } 8979 8980 ResultSet resultSet = modelFactory.createResultSet(clause.getInsertClause(), false); 8981 8982 createPseudoImpactRelation(stmt, resultSet, EffectType.merge_insert); 8983 8984 for (int j = 0; j < tableColumns.size() && j < values.size(); j++) { 8985 TObjectName columnObject = tableColumns.get(j); 8986 8987 ResultColumn insertColumn = modelFactory.createMergeResultColumn(resultSet, 8988 columnObject); 8989 8990 TExpression valueExpression = values.getResultColumn(j).getExpr(); 8991 if (valueExpression == null) 8992 continue; 8993 8994 columnsInExpr visitor = new columnsInExpr(); 8995 valueExpression.inOrderTraverse(visitor); 8996 List<TObjectName> objectNames = visitor.getObjectNames(); 8997 List<TParseTreeNode> functions = visitor.getFunctions(); 8998 8999 if (functions != null && !functions.isEmpty()) { 9000 analyzeFunctionDataFlowRelation(insertColumn, functions, EffectType.merge_insert); 9001 } 9002 9003 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 9004 if (subquerys != null && !subquerys.isEmpty()) { 9005 analyzeSubqueryDataFlowRelation(insertColumn, subquerys, EffectType.merge_insert); 9006 } 9007 9008 analyzeDataFlowRelation(insertColumn, objectNames, EffectType.merge_insert, functions); 9009 9010 List<TParseTreeNode> constants = visitor.getConstants(); 9011 analyzeConstantDataFlowRelation(insertColumn, constants, EffectType.merge_insert, 9012 functions); 9013 9014 TableColumn tableColumn = modelFactory.createTableColumn(((Table)tableModel), columnObject, 9015 false); 9016 if(tableColumn == null) { 9017 if (((Table) tableModel).isCreateTable()) { 9018 tableColumn = ((Table) tableModel).getColumns().get(j); 9019 } 9020 else { 9021 continue; 9022 } 9023 } 9024 9025 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9026 relation.setEffectType(EffectType.merge_insert); 9027 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9028 relation.addSource(new ResultColumnRelationshipElement(insertColumn)); 9029 relation.setProcess(process); 9030 } 9031 } 9032 } 9033 } 9034 9035 } 9036 9037 if (stmt.getCondition() != null) { 9038 analyzeFilterCondition(null, stmt.getCondition(), null, JoinClauseType.on, EffectType.merge); 9039 } 9040 } 9041 } 9042 9043 private List<TableColumn> bindInsertTableColumn(Table tableModel, TInsertIntoValue value, List<TObjectName> keyMap, 9044 List<TResultColumn> valueMap) { 9045 List<TableColumn> tableColumns = new ArrayList<TableColumn>(); 9046 if (value.getColumnList() != null) { 9047 for (int z = 0; z < value.getColumnList().size(); z++) { 9048 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 9049 value.getColumnList().getObjectName(z)); 9050 tableColumns.add(tableColumn); 9051 keyMap.add(tableColumn.getColumnObject()); 9052 } 9053 } 9054 9055 if (value.getTargetList() != null) { 9056 for (int z = 0; z < value.getTargetList().size(); z++) { 9057 TMultiTarget target = value.getTargetList().getMultiTarget(z); 9058 TResultColumnList columns = target.getColumnList(); 9059 for (int i = 0; i < columns.size(); i++) { 9060 if (value.getColumnList() == null) { 9061 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 9062 columns.getResultColumn(i).getFieldAttr()); 9063 tableColumns.add(tableColumn); 9064 } 9065 valueMap.add(columns.getResultColumn(i)); 9066 } 9067 } 9068 } 9069 9070 return tableColumns; 9071 } 9072 9073 private TableColumn matchColumn(List<TableColumn> tableColumns, TableColumn targetColumn) { 9074 String columnName = targetColumn.getName(); 9075 if (tableColumns == null) { 9076 return null; 9077 } 9078 for (int i = 0; i < tableColumns.size(); i++) { 9079 TableColumn column = tableColumns.get(i); 9080 if (column.getColumnObject() == null) { 9081 continue; 9082 } 9083 if(column.isStruct() && targetColumn.isStruct()) { 9084 List<String> names = SQLUtil.parseNames(column.getName()); 9085 List<String> targetNames = SQLUtil 9086 .parseNames(targetColumn.getName()); 9087 if (!getColumnName(targetNames.get(0)) 9088 .equals(getColumnName(names.get(0)))) { 9089 continue; 9090 } 9091 } 9092 if (getColumnName(column.getColumnObject().toString()).equals(getColumnName(columnName))) { 9093 return column; 9094 } 9095 } 9096 return null; 9097 } 9098 9099 private TableColumn matchColumn(List<TableColumn> tableColumns, TObjectName columnName) { 9100 if (tableColumns == null) { 9101 return null; 9102 } 9103 for (int i = 0; i < tableColumns.size(); i++) { 9104 TableColumn column = tableColumns.get(i); 9105 if (column.getColumnObject() == null) { 9106 continue; 9107 } 9108 if (DlineageUtil.getColumnName(column.getColumnObject()).equalsIgnoreCase(DlineageUtil.getColumnName(columnName))) 9109 return column; 9110 } 9111 return null; 9112 } 9113 9114 private ResultColumn matchResultColumn(List<ResultColumn> resultColumns, ResultColumn resultColumn) { 9115 if (resultColumns == null) { 9116 return null; 9117 } 9118 9119 TObjectName columnName = getObjectName(resultColumn); 9120 if (columnName == null) { 9121 return null; 9122 } 9123 9124 for (int i = 0; i < resultColumns.size(); i++) { 9125 ResultColumn column = resultColumns.get(i); 9126 if (column.getAlias() != null 9127 && getColumnName(column.getAlias()).equalsIgnoreCase(getColumnName(columnName))) 9128 return column; 9129 if (column.getName() != null && getColumnName(column.getName()).equalsIgnoreCase(getColumnName(columnName))) 9130 return column; 9131 if (column.getName() != null && column.getName().endsWith("*")) { 9132 if ("*".equals(column.getColumnObject().toString())) { 9133 return column; 9134 } else { 9135 TObjectName columnObjectName = getObjectName(column); 9136 if (columnObjectName.getTableString() != null 9137 && columnObjectName.getTableString().equals(getResultSetAlias(resultColumn))) { 9138 return column; 9139 } 9140 } 9141 } 9142 } 9143 return null; 9144 } 9145 9146 private String getResultSetAlias(ResultColumn resultColumn) { 9147 ResultSet resultSet = resultColumn.getResultSet(); 9148 if (resultSet instanceof QueryTable) { 9149 return ((QueryTable) resultSet).getAlias(); 9150 } 9151 return null; 9152 } 9153 9154 private ResultColumn matchResultColumn(List<ResultColumn> resultColumns, TObjectName columnName) { 9155 if (resultColumns == null) { 9156 return null; 9157 } 9158 for (int i = 0; i < resultColumns.size(); i++) { 9159 ResultColumn column = resultColumns.get(i); 9160 if (column.getAlias() != null 9161 && getColumnName(column.getAlias()).equalsIgnoreCase(getColumnName(columnName))) 9162 return column; 9163 if (column.getName() != null && getColumnName(column.getName()).equalsIgnoreCase(getColumnName(columnName))) 9164 return column; 9165 if (column.getName() != null && column.getName().endsWith("*")) { 9166 if ("*".equals(column.getColumnObject().toString())) { 9167 return column; 9168 } else { 9169 TObjectName columnObjectName = getObjectName(column); 9170 if (columnObjectName.getTableString() != null 9171 && columnObjectName.getTableString().equals(columnName.getTableString())) { 9172 return column; 9173 } 9174 } 9175 } 9176 } 9177 return null; 9178 } 9179 9180 private void analyzeInsertStmt(TInsertSqlStatement stmt) { 9181 Map<Table, List<TObjectName>> insertTableKeyMap = new LinkedHashMap<Table, List<TObjectName>>(); 9182 Map<Table, List<TResultColumn>> insertTableValueMap = new LinkedHashMap<Table, List<TResultColumn>>(); 9183 Map<String, List<TableColumn>> tableColumnMap = new LinkedHashMap<String, List<TableColumn>>(); 9184 List<Table> inserTables = new ArrayList<Table>(); 9185 List<TExpression> expressions = new ArrayList<TExpression>(); 9186 boolean hasInsertColumns = false; 9187 9188 EffectType effectType = EffectType.insert; 9189 if(stmt.getInsertToken()!=null && stmt.getInsertToken().toString().toLowerCase().startsWith("replace")) { 9190 effectType = EffectType.replace; 9191 } 9192 9193 if (stmt.getInsertConditions() != null && stmt.getInsertConditions().size() > 0) { 9194 for (int i = 0; i < stmt.getInsertConditions().size(); i++) { 9195 TInsertCondition condition = stmt.getInsertConditions().getElement(i); 9196 if (condition.getCondition() != null) { 9197 expressions.add(condition.getCondition()); 9198 } 9199 for (int j = 0; j < condition.getInsertIntoValues().size(); j++) { 9200 TInsertIntoValue value = condition.getInsertIntoValues().getElement(j); 9201 TTable table = value.getTable(); 9202 Table tableModel = modelFactory.createTable(table); 9203 9204 inserTables.add(tableModel); 9205 List<TObjectName> keyMap = new ArrayList<TObjectName>(); 9206 List<TResultColumn> valueMap = new ArrayList<TResultColumn>(); 9207 insertTableKeyMap.put(tableModel, keyMap); 9208 insertTableValueMap.put(tableModel, valueMap); 9209 9210 List<TableColumn> tableColumns = bindInsertTableColumn(tableModel, value, keyMap, valueMap); 9211 if (tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(table.getFullName())) == null 9212 && !tableColumns.isEmpty()) { 9213 tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()), 9214 tableColumns); 9215 } 9216 9217 // if (stmt.getSubQuery() != null) 9218 { 9219 Process process = modelFactory.createProcess(stmt); 9220 tableModel.addProcess(process); 9221 } 9222 } 9223 } 9224 hasInsertColumns = true; 9225 } else if (stmt.getInsertIntoValues() != null && stmt.getInsertIntoValues().size() > 0) { 9226 for (int i = 0; i < stmt.getInsertIntoValues().size(); i++) { 9227 TInsertIntoValue value = stmt.getInsertIntoValues().getElement(i); 9228 TTable table = value.getTable(); 9229 Table tableModel = modelFactory.createTable(table); 9230 9231 inserTables.add(tableModel); 9232 List<TObjectName> keyMap = new ArrayList<TObjectName>(); 9233 List<TResultColumn> valueMap = new ArrayList<TResultColumn>(); 9234 insertTableKeyMap.put(tableModel, keyMap); 9235 insertTableValueMap.put(tableModel, valueMap); 9236 9237 List<TableColumn> tableColumns = bindInsertTableColumn(tableModel, value, keyMap, valueMap); 9238 if (tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName())) == null && !tableColumns.isEmpty()) { 9239 tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()), tableColumns); 9240 } 9241 9242 // if (stmt.getSubQuery() != null) 9243 { 9244 Process process = modelFactory.createProcess(stmt); 9245 tableModel.addProcess(process); 9246 } 9247 } 9248 hasInsertColumns = true; 9249 } else if (stmt.getColumnList() != null && stmt.getColumnList().size() > 0) { 9250 TTable table = stmt.getTargetTable(); 9251 Table tableModel = modelFactory.createTable(table); 9252 9253 inserTables.add(tableModel); 9254 List<TObjectName> keyMap = new ArrayList<TObjectName>(); 9255 insertTableKeyMap.put(tableModel, keyMap); 9256 List<TableColumn> tableColumns = new ArrayList<TableColumn>(); 9257 for (int i = 0; i < stmt.getColumnList().size(); i++) { 9258 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 9259 stmt.getColumnList().getObjectName(i)); 9260 tableColumns.add(tableColumn); 9261 } 9262 if (tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName())) == null && !tableColumns.isEmpty()) { 9263 tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()), tableColumns); 9264 } 9265 9266 // if (stmt.getSubQuery() != null) 9267 { 9268 Process process = modelFactory.createProcess(stmt); 9269 tableModel.addProcess(process); 9270 } 9271 hasInsertColumns = true; 9272 } else if (stmt.getOutputClause() != null && stmt.getOutputClause().getSelectItemList().size() > 0) { 9273 TTable table = stmt.getTargetTable(); 9274 Table tableModel = modelFactory.createTable(table); 9275 9276 inserTables.add(tableModel); 9277 List<TObjectName> keyMap = new ArrayList<TObjectName>(); 9278 insertTableKeyMap.put(tableModel, keyMap); 9279 List<TableColumn> tableColumns = new ArrayList<TableColumn>(); 9280 for (int i = 0; i < stmt.getOutputClause().getSelectItemList().size(); i++) { 9281 TObjectName columnName = stmt.getOutputClause().getSelectItemList().getResultColumn(i).getFieldAttr(); 9282 if (columnName.getPseudoTableType() != EPseudoTableType.none) { 9283 // Phase 1 already swapped tokens; getColumnNameOnly() returns actual column name 9284 String column = columnName.getColumnNameOnly(); 9285 columnName = new TObjectName(); 9286 columnName.setString(column); 9287 } else { 9288 String column = columnName.toString().toLowerCase(); 9289 if ((column.startsWith("inserted.") || column.startsWith("deleted.")) 9290 && columnName.getPropertyToken() != null) { 9291 column = columnName.getPropertyToken().getAstext(); 9292 columnName = new TObjectName(); 9293 columnName.setString(column); 9294 } 9295 } 9296 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, columnName); 9297 tableColumns.add(tableColumn); 9298 } 9299 if (tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName())) == null && !tableColumns.isEmpty()) { 9300 tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()), tableColumns); 9301 } 9302 9303 // if (stmt.getSubQuery() != null) 9304 { 9305 Process process = modelFactory.createProcess(stmt); 9306 tableModel.addProcess(process); 9307 } 9308 hasInsertColumns = true; 9309 } else { 9310 TTable table = stmt.getTargetTable(); 9311 Table tableModel; 9312 if (table != null) { 9313 tableModel = modelFactory.createTable(table); 9314 // if (stmt.getSubQuery() != null) 9315 { 9316 Process process = modelFactory.createProcess(stmt); 9317 tableModel.addProcess(process); 9318 } 9319 if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) { 9320 tableModel.addColumnsFromSQLEnv(); 9321 } 9322 } else if (stmt.getDirectoryName() != null) { 9323 tableModel = modelFactory.createTableByName(stmt.getDirectoryName(), true); 9324 tableModel.setPath(true); 9325 tableModel.setCreateTable(true); 9326 TObjectName fileUri = new TObjectName(); 9327 fileUri.setString("uri=" + stmt.getDirectoryName()); 9328 TableColumn tableColumn = modelFactory.createFileUri(tableModel, fileUri); 9329 // if (stmt.getSubQuery() != null) 9330 { 9331 Process process = modelFactory.createProcess(stmt); 9332 tableModel.addProcess(process); 9333 } 9334 } else { 9335 ErrorInfo errorInfo = new ErrorInfo(); 9336 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 9337 errorInfo.setErrorMessage("Can't get target table. InsertSqlStatement is " + stmt.toString()); 9338 errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo, 9339 stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash())); 9340 errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo, 9341 stmt.getEndToken().columnNo + stmt.getEndToken().getAstext().length(), 9342 ModelBindingManager.getGlobalHash())); 9343 errorInfo.fillInfo(this); 9344 errorInfos.add(errorInfo); 9345 return; 9346 } 9347 inserTables.add(tableModel); 9348 if (table != null 9349 && tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(table.getFullName())) == null) { 9350 if (tableModel.getColumns() != null && !tableModel.getColumns().isEmpty()) { 9351 tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()), 9352 tableModel.getColumns()); 9353 } else { 9354 tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()), null); 9355 } 9356 } 9357 } 9358 9359 if (stmt.getSubQuery() != null) { 9360 analyzeSelectStmt(stmt.getSubQuery()); 9361 } 9362 9363 Iterator<Table> tableIter = inserTables.iterator(); 9364 while (tableIter.hasNext()) { 9365 Table tableModel = tableIter.next(); 9366 List<TableColumn> tableColumns = tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName())); 9367 List<TObjectName> keyMap = insertTableKeyMap.get(tableModel); 9368 List<TResultColumn> valueMap = insertTableValueMap.get(tableModel); 9369 boolean initColumn = (hasInsertColumns && tableColumns != null && !containStarColumn(tableColumns)); 9370 9371 if (stmt.getSubQuery() != null) { 9372 9373 List<TSelectSqlStatement> subquerys = new ArrayList<TSelectSqlStatement>(); 9374 if (stmt.getSubQuery().getResultColumnList() != null || stmt.getSubQuery().getTransformClause() != null) { 9375 subquerys.add(stmt.getSubQuery()); 9376 } else if (stmt.getSubQuery().getValueClause() != null 9377 && stmt.getSubQuery().getValueClause().getRows() != null) { 9378 for (TResultColumnList resultColumnList : stmt.getSubQuery().getValueClause().getRows()) { 9379 for(TResultColumn resultColumn: resultColumnList) { 9380 if(resultColumn.getExpr()!=null && resultColumn.getExpr().getSubQuery()!=null) { 9381 analyzeSelectStmt(resultColumn.getExpr().getSubQuery()); 9382 subquerys.add(resultColumn.getExpr().getSubQuery()); 9383 } 9384 } 9385 } 9386 } 9387 9388 for(TSelectSqlStatement subquery: subquerys) { 9389 if ((tableModel.isCreateTable() && tableModel.getColumns() != null) 9390 || (subquery.getSetOperatorType() == ESetOperatorType.none 9391 && stmt.getColumnList() != null && stmt.getColumnList().size() > 0)) { 9392 9393 ResultSet resultSetModel = null; 9394 9395 if (subquery != null) { 9396 resultSetModel = (ResultSet) modelManager.getModel(subquery); 9397 } 9398 9399 TResultColumnList resultset = subquery.getResultColumnList(); 9400 if (resultSetModel == null && resultset != null) { 9401 resultSetModel = (ResultSet) modelManager.getModel(resultset); 9402 } 9403 9404 if (resultSetModel == null) { 9405 ErrorInfo errorInfo = new ErrorInfo(); 9406 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 9407 errorInfo.setErrorMessage("Can't get resultset model"); 9408 errorInfo.setStartPosition(new Pair3<Long, Long, String>(resultset.getStartToken().lineNo, 9409 resultset.getStartToken().columnNo, ModelBindingManager.getGlobalHash())); 9410 errorInfo.setEndPosition(new Pair3<Long, Long, String>(resultset.getEndToken().lineNo, 9411 resultset.getEndToken().columnNo + resultset.getEndToken().getAstext().length(), 9412 ModelBindingManager.getGlobalHash())); 9413 errorInfos.add(errorInfo); 9414 } 9415 9416 if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 9417 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 9418 impactRelation.setEffectType(effectType); 9419 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 9420 resultSetModel.getRelationRows())); 9421 impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>( 9422 tableModel.getRelationRows())); 9423 } 9424 9425 int resultSetSize = resultSetModel.getColumns().size(); 9426 int j = 0; 9427 int starIndex = 0; 9428 TObjectNameList items = stmt.getColumnList(); 9429 List<String> itemNames = new ArrayList<String>(); 9430 int starColumnCount = 0; 9431 for (ResultColumn item : resultSetModel.getColumns()) { 9432 if (item.getName().endsWith("*")) { 9433 starColumnCount += 1; 9434 } 9435 } 9436 if (items != null) { 9437 for (int i = 0; i < items.size() && j < resultSetSize; i++) { 9438 TObjectName column = items.getObjectName(i); 9439 9440 if (column.getDbObjectType() == EDbObjectType.variable) { 9441 continue; 9442 } 9443 9444 if (column.getColumnNameOnly().startsWith("@") 9445 && (option.getVendor() == EDbVendor.dbvmssql 9446 || option.getVendor() == EDbVendor.dbvazuresql)) { 9447 continue; 9448 } 9449 9450 if (column.getColumnNameOnly().startsWith(":") 9451 && (option.getVendor() == EDbVendor.dbvhana 9452 || option.getVendor() == EDbVendor.dbvteradata)) { 9453 continue; 9454 } 9455 9456 ResultColumn resultColumn = resultSetModel.getColumns().get(j); 9457 if (!resultSetModel.getColumns().get(j).getName().contains("*")) { 9458 j++; 9459 } else { 9460 starIndex++; 9461 if (resultSetSize - j == items.size() - i) { 9462 j++; 9463 9464 } 9465 } 9466 if (column != null) { 9467 TableColumn tableColumn; 9468 // if (!initColumn) { 9469 tableColumn = matchColumn(tableModel.getColumns(), column); 9470 if (tableColumn == null) { 9471 if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) { 9472 if (tableModel.getColumns().size() <= i) { 9473 continue; 9474 } 9475 tableColumn = tableModel.getColumns().get(i); 9476 } else { 9477 tableColumn = modelFactory.createTableColumn(tableModel, column, false); 9478 if(tableColumn == null) { 9479 continue; 9480 } 9481 } 9482 } 9483// } else { 9484// tableColumn = matchColumn(tableColumns, column); 9485// if (tableColumn == null) { 9486// continue; 9487// } 9488// } 9489 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9490 relation.setEffectType(effectType); 9491 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9492 if (resultColumn.hasStarLinkColumn() 9493 && resultColumn.getStarLinkColumnNames().size() > starIndex - 1 && starColumnCount<=1) { 9494 boolean find = false; 9495 while (resultColumn.getStarLinkColumnNames().size() > starIndex - 1) { 9496 TObjectName name = resultColumn.getStarLinkColumnName(starIndex - 1); 9497 if (itemNames.contains(name.toString())) { 9498 starIndex++; 9499 continue; 9500 } 9501 ResultColumn expandStarColumn = modelFactory 9502 .createResultColumn(resultSetModel, name, false); 9503 relation.addSource(new ResultColumnRelationshipElement(expandStarColumn)); 9504 itemNames.add(resultColumn.getName()); 9505 find = true; 9506 break; 9507 } 9508 if (!find) { 9509 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9510 itemNames.add(resultColumn.getName()); 9511 } 9512 } else { 9513 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9514 itemNames.add(resultColumn.getName()); 9515 } 9516 Process process = modelFactory.createProcess(stmt); 9517 relation.setProcess(process); 9518 } 9519 } 9520 } else { 9521 List<TableColumn> columns = tableModel.getColumns(); 9522 if (columns.size() == 1 && tableModel.isPath()) { 9523 for(int i=0;i<resultSetSize;i++) { 9524 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 9525 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9526 relation.setEffectType(effectType); 9527 relation.setTarget(new TableColumnRelationshipElement(tableModel.getColumns().get(0))); 9528 if (resultColumn.hasStarLinkColumn() 9529 && resultColumn.getStarLinkColumnNames().size() > starIndex - 1) { 9530 ResultColumn expandStarColumn = modelFactory.createResultColumn( 9531 resultSetModel, resultColumn.getStarLinkColumnName(starIndex - 1), 9532 false); 9533 relation.addSource(new ResultColumnRelationshipElement(expandStarColumn)); 9534 } else { 9535 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9536 } 9537 Process process = modelFactory.createProcess(stmt); 9538 relation.setProcess(process); 9539 } 9540 } else { 9541 boolean fromStruct = false; 9542 for (int i = 0; i < columns.size() && j < resultSetSize; i++) { 9543 String column = columns.get(i).getName(); 9544 ResultColumn resultColumn = resultSetModel.getColumns().get(j); 9545 if (!resultColumn.getName().contains("*")) { 9546 if (resultColumn.getName().equals(resultColumn.getRefColumnName()) 9547 && resultColumn.getColumnObject().toString().endsWith("*") 9548 && resultSetSize == 1) { 9549 starIndex++; 9550 if (resultSetSize - j == columns.size() - i) { 9551 j++; 9552 9553 } 9554 } 9555 else { 9556 j++; 9557 } 9558 } else { 9559 starIndex++; 9560 if (resultSetSize - j == columns.size() - i) { 9561 j++; 9562 9563 } 9564 } 9565 if (column != null) { 9566 TableColumn tableColumn; 9567 // if (!initColumn) { 9568 tableColumn = matchColumn(tableModel.getColumns(), columns.get(i)); 9569 if (tableColumn == null) { 9570 if (tableModel.isCreateTable() 9571 && !containStarColumn(tableModel.getColumns())) { 9572 if (tableModel.getColumns().size() <= i) { 9573 continue; 9574 } 9575 tableColumn = tableModel.getColumns().get(i); 9576 } else { 9577 TObjectName columnName = new TObjectName(); 9578 columnName.setString(column); 9579 tableColumn = modelFactory.createTableColumn(tableModel, columnName, 9580 false); 9581 } 9582 } 9583 else if (!resultColumn.isStruct() && tableColumn.isStruct() && columns.size() != resultSetSize) { 9584 j--; 9585 fromStruct = true; 9586 } 9587 if(fromStruct && !tableColumn.isStruct()) { 9588 fromStruct = false; 9589 resultColumn = resultSetModel.getColumns().get(j); 9590 j++; 9591 } 9592 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9593 relation.setEffectType(effectType); 9594 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9595 if (resultColumn.hasStarLinkColumn() 9596 && resultColumn.getStarLinkColumnNames().size() > starIndex - 1) { 9597 ResultColumn expandStarColumn = modelFactory.createResultColumn( 9598 resultSetModel, resultColumn.getStarLinkColumnName(starIndex - 1), 9599 false); 9600 relation.addSource(new ResultColumnRelationshipElement(expandStarColumn)); 9601 } else { 9602 relation.addSource(new ResultColumnRelationshipElement(resultColumn, starIndex - 1)); 9603 } 9604 Process process = modelFactory.createProcess(stmt); 9605 relation.setProcess(process); 9606 } 9607 } 9608 } 9609 } 9610 } else if (!subquery.isCombinedQuery()) { 9611 SelectResultSet resultSetModel = (SelectResultSet) modelManager 9612 .getModel(subquery.getResultColumnList() != null ? subquery.getResultColumnList() 9613 : subquery.getTransformClause()); 9614 9615 if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 9616 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 9617 impactRelation.setEffectType(effectType); 9618 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 9619 resultSetModel.getRelationRows())); 9620 impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>( 9621 tableModel.getRelationRows())); 9622 } 9623 9624 List<ResultColumn> columnsSnapshot = new ArrayList<ResultColumn>(); 9625 columnsSnapshot.addAll(resultSetModel.getColumns()); 9626 if(resultSetModel.isDetermined() && stmt.getColumnList() == null) { 9627 tableModel.setDetermined(true); 9628 } 9629 for (int i = 0; i < columnsSnapshot.size(); i++) { 9630 ResultColumn resultColumn = columnsSnapshot.get(i); 9631 if (resultColumn.getColumnObject() instanceof TObjectName) { 9632 TableColumn tableColumn; 9633 if (!initColumn) { 9634 if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) { 9635 if (tableModel.getColumns().size() <= i) { 9636 continue; 9637 } 9638 tableColumn = tableModel.getColumns().get(i); 9639 } else { 9640 tableColumn = modelFactory.createInsertTableColumn(tableModel, 9641 (TObjectName) resultColumn.getColumnObject()); 9642 } 9643 if (containStarColumn(tableColumns)) { 9644 getStarColumn(tableColumns) 9645 .bindStarLinkColumn((TObjectName) resultColumn.getColumnObject()); 9646 } 9647 } else { 9648 TObjectName matchedColumnName = (TObjectName) resultColumn.getColumnObject(); 9649 tableColumn = matchColumn(tableColumns, matchedColumnName); 9650 if (tableColumn == null) { 9651 if (!isEmptyCollection(valueMap)) { 9652 int index = indexOfColumn(valueMap, matchedColumnName); 9653 if (index != -1) { 9654 if (!isEmptyCollection(keyMap) && index < keyMap.size()) { 9655 tableColumn = matchColumn(tableColumns, keyMap.get(index)); 9656 } else if (isEmptyCollection(keyMap) && index < tableColumns.size()) { 9657 tableColumn = tableColumns.get(index); 9658 } else { 9659 continue; 9660 } 9661 } else { 9662 continue; 9663 } 9664 } else if (!isEmptyCollection(keyMap) && i < keyMap.size()) { 9665 tableColumn = matchColumn(tableColumns, keyMap.get(i)); 9666 } else if (isEmptyCollection(keyMap) && isEmptyCollection(valueMap) 9667 && i < tableColumns.size()) { 9668 tableColumn = tableColumns.get(i); 9669 } else { 9670 continue; 9671 } 9672 } 9673 } 9674 9675 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9676 relation.setEffectType(effectType); 9677 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9678 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9679 Process process = modelFactory.createProcess(stmt); 9680 relation.setProcess(process); 9681 } else { 9682 TAliasClause alias = ((TResultColumn) resultColumn.getColumnObject()).getAliasClause(); 9683 if (alias != null && alias.getAliasName() != null) { 9684 TableColumn tableColumn; 9685 if (!initColumn) { 9686 if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) { 9687 if (tableModel.getColumns().size() <= i) { 9688 if (tableModel.isPath()) { 9689 tableColumn = tableModel.getColumns().get(0); 9690 } else { 9691 continue; 9692 } 9693 } else { 9694 tableColumn = tableModel.getColumns().get(i); 9695 } 9696 } else { 9697 tableColumn = modelFactory.createInsertTableColumn(tableModel, 9698 alias.getAliasName()); 9699 if (containStarColumn(resultSetModel)) { 9700 tableColumn.notBindStarLinkColumn(true); 9701 } 9702 } 9703 if (containStarColumn(tableColumns)) { 9704 getStarColumn(tableColumns).bindStarLinkColumn(alias.getAliasName()); 9705 } 9706 } else { 9707 TObjectName matchedColumnName = alias.getAliasName(); 9708 tableColumn = matchColumn(tableColumns, matchedColumnName); 9709 if (tableColumn == null) { 9710 if (!isEmptyCollection(valueMap)) { 9711 int index = indexOfColumn(valueMap, matchedColumnName); 9712 if (index != -1) { 9713 if (!isEmptyCollection(keyMap) && index < keyMap.size()) { 9714 tableColumn = matchColumn(tableColumns, keyMap.get(index)); 9715 } else if (isEmptyCollection(keyMap) 9716 && index < tableColumns.size()) { 9717 tableColumn = tableColumns.get(index); 9718 } else { 9719 continue; 9720 } 9721 } else { 9722 continue; 9723 } 9724 } else if (!isEmptyCollection(keyMap) && i < keyMap.size()) { 9725 tableColumn = matchColumn(tableColumns, keyMap.get(i)); 9726 } else { 9727 tableColumn = modelFactory.createInsertTableColumn(tableModel, 9728 alias.getAliasName()); 9729 } 9730 } 9731 9732 } 9733 9734 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9735 relation.setEffectType(effectType); 9736 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9737 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9738 Process process = modelFactory.createProcess(stmt); 9739 relation.setProcess(process); 9740 9741 } else if (((TResultColumn) resultColumn.getColumnObject()).getFieldAttr() != null) { 9742 TObjectName fieldAttr = ((TResultColumn) resultColumn.getColumnObject()) 9743 .getFieldAttr(); 9744 9745 Object model = modelManager.getModel( resultColumn.getColumnObject()); 9746 9747 TableColumn tableColumn; 9748 if (!initColumn) { 9749 if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) { 9750 if (fieldAttr.toString().endsWith("*")) { 9751 int starIndex = 0; 9752 for (TableColumn column : tableModel.getColumns()) { 9753 starIndex++; 9754 DataFlowRelationship relation = modelFactory 9755 .createDataFlowRelation(); 9756 relation.setEffectType(effectType); 9757 relation.setTarget(new TableColumnRelationshipElement(column)); 9758 if (resultColumn.getStarLinkColumnList().size() == tableModel 9759 .getColumns().size()) { 9760 ResultColumn expandStarColumn = modelFactory.createResultColumn( 9761 resultSetModel, 9762 resultColumn.getStarLinkColumnList().get(starIndex - 1), 9763 false); 9764 relation.addSource( 9765 new ResultColumnRelationshipElement(expandStarColumn)); 9766 } else { 9767 relation.addSource( 9768 new ResultColumnRelationshipElement(resultColumn)); 9769 } 9770 Process process = modelFactory.createProcess(stmt); 9771 relation.setProcess(process); 9772 } 9773 continue; 9774 } 9775 if (tableModel.getColumns().size() <= i) { 9776 continue; 9777 } 9778 tableColumn = tableModel.getColumns().get(i); 9779 } else { 9780 if(model instanceof LinkedHashMap) { 9781 LinkedHashMap<String, ResultColumn> resultColumns = (LinkedHashMap<String, ResultColumn>)model; 9782 for(String key: resultColumns.keySet()) { 9783 tableColumn = modelFactory.createInsertTableColumn(tableModel, resultColumns.get(key).getName()); 9784 DataFlowRelationship relation = modelFactory 9785 .createDataFlowRelation(); 9786 relation.setEffectType(effectType); 9787 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9788 relation.addSource( 9789 new ResultColumnRelationshipElement(resultColumns.get(key))); 9790 Process process = modelFactory.createProcess(stmt); 9791 relation.setProcess(process); 9792 } 9793 continue; 9794 } 9795 else { 9796 tableColumn = modelFactory.createInsertTableColumn(tableModel, fieldAttr); 9797 } 9798 } 9799 } else if (tableModel.isDetermined() && i < tableModel.getColumns().size()) { 9800 if (!isEmptyCollection(valueMap)) { 9801 TObjectName matchedColumnName = fieldAttr; 9802 int index = indexOfColumn(valueMap, matchedColumnName); 9803 if (index != -1) { 9804 if (!isEmptyCollection(keyMap) && index < keyMap.size()) { 9805 tableColumn = matchColumn(tableColumns, keyMap.get(index)); 9806 } else if (isEmptyCollection(keyMap) 9807 && index < tableColumns.size()) { 9808 tableColumn = tableColumns.get(index); 9809 } else { 9810 continue; 9811 } 9812 } else { 9813 continue; 9814 } 9815 } else if (!isEmptyCollection(keyMap) && i < keyMap.size()) { 9816 tableColumn = matchColumn(tableColumns, keyMap.get(i)); 9817 } else { 9818 tableColumn = tableModel.getColumns().get(i); 9819 } 9820 } else { 9821 TObjectName matchedColumnName = fieldAttr; 9822 tableColumn = matchColumn(tableColumns, matchedColumnName); 9823 if (tableColumn == null) { 9824 if (!isEmptyCollection(valueMap)) { 9825 int index = indexOfColumn(valueMap, matchedColumnName); 9826 if (index != -1) { 9827 if (!isEmptyCollection(keyMap) && index < keyMap.size()) { 9828 tableColumn = matchColumn(tableColumns, keyMap.get(index)); 9829 } else if (isEmptyCollection(keyMap) 9830 && index < tableColumns.size()) { 9831 tableColumn = tableColumns.get(index); 9832 } else { 9833 continue; 9834 } 9835 } else { 9836 continue; 9837 } 9838 } else if (!isEmptyCollection(keyMap) && i < keyMap.size()) { 9839 tableColumn = matchColumn(tableColumns, keyMap.get(i)); 9840 } else { 9841 tableColumn = modelFactory.createInsertTableColumn(tableModel, 9842 fieldAttr); 9843 } 9844 } 9845 } 9846 9847 if (!"*".equals(getColumnName(tableColumn.getColumnObject())) 9848 && "*".equals(getColumnName(fieldAttr))) { 9849 TObjectName columnObject = fieldAttr; 9850 TTable sourceTable = columnObject.getSourceTable(); 9851 if (columnObject.getTableToken() != null && sourceTable != null) { 9852 TObjectName[] columns = modelManager.getTableColumns(sourceTable); 9853 for (int j = 0; j < columns.length; j++) { 9854 TObjectName columnName = columns[j]; 9855 if (columnName == null || "*".equals(getColumnName(columnName))) { 9856 continue; 9857 } 9858 resultColumn.bindStarLinkColumn(columnName); 9859 } 9860 } else { 9861 TTableList tables = stmt.getTables(); 9862 for (int k = 0; k < tables.size(); k++) { 9863 TTable tableElement = tables.getTable(k); 9864 TObjectName[] columns = modelManager.getTableColumns(tableElement); 9865 for (int j = 0; j < columns.length; j++) { 9866 TObjectName columnName = columns[j]; 9867 if (columnName == null || "*".equals(getColumnName(columnName))) { 9868 continue; 9869 } 9870 resultColumn.bindStarLinkColumn(columnName); 9871 } 9872 } 9873 } 9874 } 9875 9876 if ("*".equals(getColumnName(tableColumn.getColumnObject())) && resultColumn != null 9877 && !resultColumn.getStarLinkColumns().isEmpty()) { 9878 tableColumn.bindStarLinkColumns(resultColumn.getStarLinkColumns()); 9879 } 9880 9881 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9882 relation.setEffectType(effectType); 9883 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9884 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9885 9886 if (tableColumn.getName().endsWith("*") && resultColumn.getName().endsWith("*")) { 9887 tableColumn.getTable().setStarStmt("insert"); 9888 } 9889 9890 Process process = modelFactory.createProcess(stmt); 9891 relation.setProcess(process); 9892 } else if (((TResultColumn) resultColumn.getColumnObject()).getExpr() 9893 .getExpressionType() == EExpressionType.simple_constant_t) { 9894 if (!initColumn) { 9895 TableColumn tableColumn; 9896 if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) { 9897 if (tableModel.getColumns().size() <= i) { 9898 continue; 9899 } 9900 tableColumn = tableModel.getColumns().get(i); 9901 } else { 9902 tableColumn = modelFactory.createInsertTableColumn(tableModel, 9903 ((TResultColumn) resultColumn.getColumnObject()).getExpr() 9904 .getConstantOperand(), 9905 i); 9906 } 9907 9908 if (DlineageUtil.isTempTable(tableModel, option.getVendor()) && sqlenv != null 9909 && tableModel.getDatabase() != null && tableModel.getSchema() != null) { 9910 TSQLSchema schema = sqlenv.getSQLSchema( 9911 tableModel.getDatabase() + "." + tableModel.getSchema(), true); 9912 if (schema != null) { 9913 TSQLTable tempTable = schema.createTable( 9914 DlineageUtil.getSimpleTableName(tableModel.getName())); 9915 tempTable.addColumn(tableColumn.getName()); 9916 } 9917 } 9918 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9919 relation.setEffectType(effectType); 9920 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9921 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9922 Process process = modelFactory.createProcess(stmt); 9923 relation.setProcess(process); 9924 } else { 9925 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9926 relation.setEffectType(effectType); 9927 relation.setTarget( 9928 new TableColumnRelationshipElement(tableModel.getColumns().get(i))); 9929 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9930 Process process = modelFactory.createProcess(stmt); 9931 relation.setProcess(process); 9932 } 9933 } else { 9934 if (!initColumn) { 9935 TableColumn tableColumn; 9936 if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) { 9937 if (tableModel.getColumns().size() <= i) { 9938 continue; 9939 } 9940 tableColumn = tableModel.getColumns().get(i); 9941 } else { 9942 tableColumn = modelFactory.createInsertTableColumn(tableModel, 9943 ((TResultColumn) resultColumn.getColumnObject()).getExpr(), i); 9944 } 9945 if (DlineageUtil.isTempTable(tableModel, option.getVendor()) && sqlenv != null 9946 && tableModel.getDatabase() != null && tableModel.getSchema() != null) { 9947 TSQLSchema schema = sqlenv.getSQLSchema( 9948 tableModel.getDatabase() + "." + tableModel.getSchema(), true); 9949 if (schema != null) { 9950 TSQLTable tempTable = schema.createTable( 9951 DlineageUtil.getSimpleTableName(tableModel.getName())); 9952 tempTable.addColumn(tableColumn.getName()); 9953 } 9954 } 9955 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9956 relation.setEffectType(effectType); 9957 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 9958 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9959 Process process = modelFactory.createProcess(stmt); 9960 relation.setProcess(process); 9961 } else { 9962 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 9963 relation.setEffectType(effectType); 9964 relation.setTarget( 9965 new TableColumnRelationshipElement(tableModel.getColumns().get(i))); 9966 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 9967 Process process = modelFactory.createProcess(stmt); 9968 relation.setProcess(process); 9969 } 9970 } 9971 } 9972 } 9973 } else if (stmt.getSubQuery() != null) { 9974 ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubQuery()); 9975 if (resultSetModel != null) { 9976 9977 if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 9978 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 9979 impactRelation.setEffectType(effectType); 9980 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 9981 resultSetModel.getRelationRows())); 9982 impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>( 9983 tableModel.getRelationRows())); 9984 } 9985 9986 if(stmt.getColumnList()!=null && stmt.getColumnList().size()>0) { 9987 for(int i=0;i<stmt.getColumnList().size();i++) { 9988 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 9989 stmt.getColumnList().getObjectName(i)); 9990 } 9991 9992 List<TableColumn> columns = tableModel.getColumns(); 9993 int resultSetSize = resultSetModel.getColumns().size(); 9994 int starIndex = 0; 9995 int j = 0; 9996 boolean fromStruct = false; 9997 for (int i = 0; i < columns.size() && j < resultSetSize; i++) { 9998 String column = columns.get(i).getName(); 9999 ResultColumn resultColumn = resultSetModel.getColumns().get(j); 10000 if (!resultColumn.getName().contains("*")) { 10001 if (resultColumn.getName().equals(resultColumn.getRefColumnName()) 10002 && resultColumn.getColumnObject().toString().endsWith("*") 10003 && resultSetSize == 1) { 10004 starIndex++; 10005 if (resultSetSize - j == columns.size() - i) { 10006 j++; 10007 10008 } 10009 } 10010 else { 10011 j++; 10012 } 10013 } else { 10014 starIndex++; 10015 if (resultSetSize - j == columns.size() - i) { 10016 j++; 10017 10018 } 10019 } 10020 if (column != null) { 10021 TableColumn tableColumn; 10022 // if (!initColumn) { 10023 tableColumn = matchColumn(tableModel.getColumns(), columns.get(i)); 10024 if (tableColumn == null) { 10025 if (tableModel.isCreateTable() 10026 && !containStarColumn(tableModel.getColumns())) { 10027 if (tableModel.getColumns().size() <= i) { 10028 continue; 10029 } 10030 tableColumn = tableModel.getColumns().get(i); 10031 } else { 10032 TObjectName columnName = new TObjectName(); 10033 columnName.setString(column); 10034 tableColumn = modelFactory.createTableColumn(tableModel, columnName, 10035 false); 10036 } 10037 } 10038 else if (!resultColumn.isStruct() && tableColumn.isStruct() && columns.size() != resultSetSize) { 10039 j--; 10040 fromStruct = true; 10041 } 10042 if(fromStruct && !tableColumn.isStruct()) { 10043 fromStruct = false; 10044 resultColumn = resultSetModel.getColumns().get(j); 10045 j++; 10046 } 10047 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10048 relation.setEffectType(effectType); 10049 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 10050 if (resultColumn.hasStarLinkColumn() 10051 && resultColumn.getStarLinkColumnNames().size() > starIndex - 1) { 10052 ResultColumn expandStarColumn = modelFactory.createResultColumn( 10053 resultSetModel, resultColumn.getStarLinkColumnName(starIndex - 1), 10054 false); 10055 relation.addSource(new ResultColumnRelationshipElement(expandStarColumn)); 10056 } else { 10057 relation.addSource(new ResultColumnRelationshipElement(resultColumn, starIndex - 1)); 10058 } 10059 Process process = modelFactory.createProcess(stmt); 10060 relation.setProcess(process); 10061 } 10062 } 10063 } 10064 else { 10065 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 10066 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 10067 TAliasClause alias = null; 10068 if(resultColumn.getColumnObject() instanceof TResultColumn) { 10069 alias = ((TResultColumn) resultColumn.getColumnObject()).getAliasClause(); 10070 } 10071 if (stmt.getColumnList() != null) { 10072 if (i < stmt.getColumnList().size()) { 10073 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10074 relation.setEffectType(effectType); 10075 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 10076 stmt.getColumnList().getObjectName(i)); 10077 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 10078 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10079 Process process = modelFactory.createProcess(stmt); 10080 relation.setProcess(process); 10081 } 10082 } else { 10083 if (alias != null && alias.getAliasName() != null) { 10084 TableColumn tableColumn; 10085 if (!initColumn) { 10086 if (tableModel.isCreateTable() 10087 && !containStarColumn(tableModel.getColumns())) { 10088 if (tableModel.getColumns().size() <= i) { 10089 continue; 10090 } 10091 tableColumn = tableModel.getColumns().get(i); 10092 } else { 10093 tableColumn = modelFactory.createInsertTableColumn(tableModel, 10094 alias.getAliasName()); 10095 } 10096 } else { 10097 tableColumn = matchColumn(tableColumns, alias.getAliasName()); 10098 if (tableColumn == null) { 10099 continue; 10100 } 10101 } 10102 10103 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10104 relation.setEffectType(effectType); 10105 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 10106 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10107 Process process = modelFactory.createProcess(stmt); 10108 relation.setProcess(process); 10109 } else if (resultColumn.getColumnObject() instanceof TObjectName 10110 || ( resultColumn.getColumnObject() instanceof TResultColumn && ((TResultColumn) resultColumn.getColumnObject()) 10111 .getFieldAttr() != null)) { 10112 TObjectName fieldAttr = null; 10113 if (resultColumn.getColumnObject() instanceof TObjectName) { 10114 fieldAttr = (TObjectName)resultColumn.getColumnObject(); 10115 } 10116 else if (resultColumn.getColumnObject() instanceof TResultColumn) { 10117 fieldAttr = ((TResultColumn) resultColumn.getColumnObject()) 10118 .getFieldAttr(); 10119 } 10120 10121 TableColumn tableColumn; 10122 if (!initColumn) { 10123 if (tableModel.isCreateTable() 10124 && !containStarColumn(tableModel.getColumns())) { 10125 if (tableModel.getColumns().size() <= i) { 10126 continue; 10127 } 10128 tableColumn = tableModel.getColumns().get(i); 10129 } else { 10130 tableColumn = modelFactory.createInsertTableColumn(tableModel, 10131 fieldAttr); 10132 } 10133 } else { 10134 tableColumn = matchColumn(tableColumns, fieldAttr); 10135 if (tableColumn == null) { 10136 continue; 10137 } 10138 } 10139 10140 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10141 relation.setEffectType(effectType); 10142 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 10143 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10144 Process process = modelFactory.createProcess(stmt); 10145 relation.setProcess(process); 10146 } else if (((TResultColumn) resultColumn.getColumnObject()).getExpr() 10147 .getExpressionType() == EExpressionType.simple_constant_t) { 10148 if (!initColumn) { 10149 TableColumn tableColumn; 10150 if (tableModel.isCreateTable() 10151 && !containStarColumn(tableModel.getColumns())) { 10152 if (tableModel.getColumns().size() <= i) { 10153 continue; 10154 } 10155 tableColumn = tableModel.getColumns().get(i); 10156 } else { 10157 tableColumn = modelFactory.createInsertTableColumn(tableModel, 10158 ((TResultColumn) resultColumn.getColumnObject()).getExpr() 10159 .getConstantOperand(), 10160 i); 10161 } 10162 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10163 relation.setEffectType(effectType); 10164 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 10165 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10166 Process process = modelFactory.createProcess(stmt); 10167 relation.setProcess(process); 10168 } 10169 } else { 10170 if (!initColumn) { 10171 TableColumn tableColumn; 10172 if (tableModel.isCreateTable() 10173 && !containStarColumn(tableModel.getColumns())) { 10174 if (tableModel.getColumns().size() <= i) { 10175 continue; 10176 } 10177 tableColumn = tableModel.getColumns().get(i); 10178 } else { 10179 tableColumn = modelFactory.createInsertTableColumn(tableModel, 10180 ((TResultColumn) resultColumn.getColumnObject()).getExpr(), i); 10181 } 10182 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10183 relation.setEffectType(effectType); 10184 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 10185 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10186 Process process = modelFactory.createProcess(stmt); 10187 relation.setProcess(process); 10188 } 10189 } 10190 } 10191 } 10192 } 10193 } 10194 } 10195 } 10196 } else if (stmt.getColumnList() != null && stmt.getColumnList().size() > 0) { 10197 TObjectNameList items = stmt.getColumnList(); 10198 TMultiTargetList values = stmt.getValues(); 10199 if (values != null) { 10200 for (int k = 0; values != null && k < values.size(); k++) { 10201 int j = 0; 10202 for (int i = 0; i < items.size(); i++) { 10203 TObjectName column = items.getObjectName(i); 10204 TableColumn tableColumn; 10205 if (!initColumn) { 10206 if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) { 10207 if (tableModel.getColumns().size() <= i) { 10208 continue; 10209 } 10210 tableColumn = tableModel.getColumns().get(i); 10211 } else { 10212 tableColumn = modelFactory.createInsertTableColumn(tableModel, column); 10213 } 10214 } else { 10215 tableColumn = matchColumn(tableColumns, column); 10216 if (tableColumn == null) { 10217 continue; 10218 } 10219 } 10220 TResultColumn columnObject = values.getMultiTarget(k).getColumnList().getResultColumn(j); 10221 if (columnObject == null) { 10222 continue; 10223 } 10224 TExpression valueExpr = columnObject.getExpr(); 10225 columnsInExpr visitor = new columnsInExpr(); 10226 valueExpr.inOrderTraverse(visitor); 10227 List<TObjectName> objectNames = visitor.getObjectNames(); 10228 List<TParseTreeNode> constants = visitor.getConstants(); 10229 List<TParseTreeNode> functions = visitor.getFunctions(); 10230 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 10231 10232 Process process = modelFactory.createProcess(stmt); 10233 10234 10235 10236 if (functions != null && !functions.isEmpty()) { 10237 analyzeFunctionDataFlowRelation(tableColumn, functions, effectType, process); 10238 } 10239 10240 if (subquerys != null && !subquerys.isEmpty()) { 10241 analyzeSubqueryDataFlowRelation(tableColumn, subquerys, effectType, process); 10242 } 10243 if (objectNames != null && !objectNames.isEmpty()) { 10244 analyzeDataFlowRelation(tableColumn, objectNames, null, effectType, functions, 10245 process, i); 10246 } 10247 //insert into values generate too many constant relations, ignore constant relations. 10248 if (constants != null && !constants.isEmpty()) { 10249 if (!option.isIgnoreInsertIntoValues() || stmt.getParentStmt() != null) { 10250 analyzeConstantDataFlowRelation(tableColumn, constants, effectType, 10251 functions, process); 10252 } 10253 } 10254 j++; 10255 } 10256 } 10257 } else if (stmt.getExecuteStmt() != null && stmt.getExecuteStmt().getModuleName() != null) { 10258 analyzeCustomSqlStmt(stmt.getExecuteStmt()); 10259 Procedure procedure = modelManager.getProcedureByName(DlineageUtil 10260 .getIdentifierNormalTableName(stmt.getExecuteStmt().getModuleName().toString())); 10261 if (procedure!=null && procedure.getProcedureObject() instanceof TStoredProcedureSqlStatement) { 10262 TStoredProcedureSqlStatement procedureStmt = (TStoredProcedureSqlStatement) procedure 10263 .getProcedureObject(); 10264 List<TSelectSqlStatement> stmtItems = getLastSelectStmt(procedureStmt); 10265 if (stmtItems != null) { 10266 for(TSelectSqlStatement stmtItem: stmtItems) { 10267 ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmtItem); 10268 if (resultSetModel != null) { 10269 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 10270 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 10271 Transform transform = new Transform(); 10272 transform.setType(Transform.FUNCTION); 10273 transform.setCode(stmt.getExecuteStmt().getModuleName()); 10274 resultColumn.setTransform(transform); 10275 10276 if (stmt.getColumnList() != null) { 10277 if (i < stmt.getColumnList().size()) { 10278 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10279 relation.setEffectType(effectType); 10280 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 10281 stmt.getColumnList().getObjectName(i)); 10282 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 10283 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10284 Process process = modelFactory.createProcess(stmt); 10285 relation.setProcess(process); 10286 } 10287 } else { 10288 if (resultColumn.getColumnObject() instanceof TObjectName) { 10289 TObjectName fieldAttr = ((TObjectName) resultColumn.getColumnObject()); 10290 TableColumn tableColumn; 10291 if (!initColumn) { 10292 if (tableModel.isCreateTable() 10293 && !containStarColumn(tableModel.getColumns())) { 10294 if (tableModel.getColumns().size() <= i) { 10295 continue; 10296 } 10297 tableColumn = tableModel.getColumns().get(i); 10298 } else { 10299 tableColumn = modelFactory.createInsertTableColumn(tableModel, 10300 fieldAttr); 10301 } 10302 } else { 10303 tableColumn = matchColumn(tableColumns, fieldAttr); 10304 if (tableColumn == null) { 10305 continue; 10306 } 10307 } 10308 10309 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10310 relation.setEffectType(effectType); 10311 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 10312 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10313 Process process = modelFactory.createProcess(stmt); 10314 relation.setProcess(process); 10315 10316 10317 } else { 10318 TAliasClause alias = ((TResultColumn) resultColumn.getColumnObject()) 10319 .getAliasClause(); 10320 if (alias != null && alias.getAliasName() != null) { 10321 TableColumn tableColumn; 10322 if (!initColumn) { 10323 if (tableModel.isCreateTable() 10324 && !containStarColumn(tableModel.getColumns())) { 10325 if (tableModel.getColumns().size() <= i) { 10326 continue; 10327 } 10328 tableColumn = tableModel.getColumns().get(i); 10329 } else { 10330 tableColumn = modelFactory.createInsertTableColumn(tableModel, 10331 alias.getAliasName()); 10332 } 10333 } else { 10334 tableColumn = matchColumn(tableColumns, alias.getAliasName()); 10335 if (tableColumn == null) { 10336 continue; 10337 } 10338 } 10339 10340 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10341 relation.setEffectType(effectType); 10342 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 10343 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10344 Process process = modelFactory.createProcess(stmt); 10345 relation.setProcess(process); 10346 } else if (((TResultColumn) resultColumn.getColumnObject()) 10347 .getFieldAttr() != null) { 10348 TObjectName fieldAttr = ((TResultColumn) resultColumn.getColumnObject()) 10349 .getFieldAttr(); 10350 TableColumn tableColumn; 10351 if (!initColumn) { 10352 if (tableModel.isCreateTable() 10353 && !containStarColumn(tableModel.getColumns())) { 10354 if (tableModel.getColumns().size() <= i) { 10355 continue; 10356 } 10357 tableColumn = tableModel.getColumns().get(i); 10358 } else { 10359 tableColumn = modelFactory.createInsertTableColumn(tableModel, 10360 fieldAttr); 10361 } 10362 } else { 10363 tableColumn = matchColumn(tableColumns, fieldAttr); 10364 if (tableColumn == null) { 10365 continue; 10366 } 10367 } 10368 10369 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10370 relation.setEffectType(effectType); 10371 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 10372 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10373 Process process = modelFactory.createProcess(stmt); 10374 relation.setProcess(process); 10375 } else if (((TResultColumn) resultColumn.getColumnObject()).getExpr() 10376 .getExpressionType() == EExpressionType.simple_constant_t) { 10377 if (!initColumn) { 10378 TableColumn tableColumn; 10379 if (tableModel.isCreateTable() 10380 && !containStarColumn(tableModel.getColumns())) { 10381 if (tableModel.getColumns().size() <= i) { 10382 continue; 10383 } 10384 tableColumn = tableModel.getColumns().get(i); 10385 } else { 10386 tableColumn = modelFactory.createInsertTableColumn(tableModel, 10387 ((TResultColumn) resultColumn.getColumnObject()).getExpr() 10388 .getConstantOperand(), 10389 i); 10390 } 10391 10392 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10393 relation.setEffectType(effectType); 10394 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 10395 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10396 Process process = modelFactory.createProcess(stmt); 10397 relation.setProcess(process); 10398 } 10399 } else { 10400 if (!initColumn) { 10401 TableColumn tableColumn; 10402 if (tableModel.isCreateTable() 10403 && !containStarColumn(tableModel.getColumns())) { 10404 if (tableModel.getColumns().size() <= i) { 10405 continue; 10406 } 10407 tableColumn = tableModel.getColumns().get(i); 10408 } else { 10409 tableColumn = modelFactory.createInsertTableColumn(tableModel, 10410 ((TResultColumn) resultColumn.getColumnObject()).getExpr(), 10411 i); 10412 } 10413 10414 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10415 relation.setEffectType(effectType); 10416 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 10417 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10418 Process process = modelFactory.createProcess(stmt); 10419 relation.setProcess(process); 10420 } 10421 } 10422 } 10423 } 10424 } 10425 } 10426 } 10427 } 10428 } 10429 else if (procedure!=null && procedure.getProcedureObject() instanceof TObjectName) { 10430 TObjectName functionName = new TObjectName(); 10431 functionName.setString(procedure.getName()); 10432 Function function = (Function)createFunction(functionName); 10433 if (stmt.getColumnList() != null) { 10434 for (int i = 0; i < stmt.getColumnList().size(); i++) { 10435 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10436 relation.setEffectType(effectType); 10437 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 10438 stmt.getColumnList().getObjectName(i)); 10439 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 10440 relation.addSource(new ResultColumnRelationshipElement(function.getColumns().get(0))); 10441 Process process = modelFactory.createProcess(stmt); 10442 relation.setProcess(process); 10443 } 10444 } 10445 } 10446 } 10447 } else if (stmt.getValues() != null && stmt.getValues().size() > 0 && tableModel.isCreateTable() && !tableModel.getColumns().isEmpty()) { 10448 for (int k = 0; stmt.getValues() != null && k < stmt.getValues().size(); k++) { 10449 TResultColumnList columns = stmt.getValues().getMultiTarget(k).getColumnList(); 10450 boolean allConstant = true; 10451 Process process = modelFactory.createProcess(stmt); 10452 for (int x = 0; x < columns.size(); x++) { 10453 TableColumn tableColumn = tableModel.getColumns().get(x); 10454 TResultColumn columnObject = columns.getResultColumn(x); 10455 if (columnObject == null) { 10456 continue; 10457 } 10458 TExpression valueExpr = columnObject.getExpr(); 10459 columnsInExpr visitor = new columnsInExpr(); 10460 valueExpr.inOrderTraverse(visitor); 10461 List<TObjectName> objectNames = visitor.getObjectNames(); 10462 List<TParseTreeNode> constants = visitor.getConstants(); 10463 List<TParseTreeNode> functions = visitor.getFunctions(); 10464 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 10465 10466 if (functions != null && !functions.isEmpty()) { 10467 analyzeFunctionDataFlowRelation(tableColumn, functions, effectType, process); 10468 allConstant = false; 10469 } 10470 10471 if (subquerys != null && !subquerys.isEmpty()) { 10472 analyzeSubqueryDataFlowRelation(tableColumn, subquerys, effectType, process); 10473 allConstant = false; 10474 } 10475 if (objectNames != null && !objectNames.isEmpty()) { 10476 analyzeDataFlowRelation(tableColumn, objectNames, null, effectType, functions, 10477 process); 10478 allConstant = false; 10479 } 10480 //insert into values generate too many constant relations, ignore constant relations. 10481 if (constants != null && !constants.isEmpty() && stmt.getParentStmt() != null) { 10482 analyzeConstantDataFlowRelation(tableColumn, constants, effectType, functions, 10483 process); 10484 allConstant = false; 10485 } 10486 } 10487 10488 if(allConstant) { 10489 modelManager.unbindProcessModel(stmt); 10490 tableModel.removeProcess(process); 10491 } 10492 } 10493 } else if (stmt.getRecordName() != null) { 10494 String procedureName = DlineageUtil.getProcedureParentName(stmt); 10495 String variableString = stmt.getRecordName().toString(); 10496 if (variableString.startsWith(":")) { 10497 variableString = variableString.substring(variableString.indexOf(":") + 1); 10498 } 10499 if (!SQLUtil.isEmpty(procedureName)) { 10500 variableString = procedureName + "." + SQLUtil.getIdentifierNormalTableName(variableString); 10501 } 10502 10503 Table recordTable = modelManager 10504 .getTableByName(DlineageUtil.getTableFullName(variableString)); 10505 if (recordTable != null) { 10506 for (int i = 0; i < recordTable.getColumns().size(); i++) { 10507 TableColumn sourceTableColumn = recordTable.getColumns().get(i); 10508 TableColumn targetTableColumn = modelFactory.createTableColumn(tableModel, 10509 sourceTableColumn.getColumnObject(), false); 10510 if (targetTableColumn != null) { 10511 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10512 relation.setEffectType(effectType); 10513 relation.setTarget(new TableColumnRelationshipElement(targetTableColumn)); 10514 relation.addSource(new TableColumnRelationshipElement(sourceTableColumn)); 10515 Process process = modelFactory.createProcess(stmt); 10516 relation.setProcess(process); 10517 } else if (sourceTableColumn.getName().endsWith("*") && tableModel.isCreateTable()) { 10518 for (TableColumn column : tableModel.getColumns()) { 10519 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10520 relation.setEffectType(effectType); 10521 relation.setTarget(new TableColumnRelationshipElement(column)); 10522 relation.addSource(new TableColumnRelationshipElement(sourceTableColumn)); 10523 Process process = modelFactory.createProcess(stmt); 10524 relation.setProcess(process); 10525 } 10526 } 10527 } 10528 } 10529 } else if (stmt.getInsertSource() == EInsertSource.values_function && stmt.getFunctionCall() != null) { 10530 Table cursor = modelManager.getTableByName( 10531 DlineageUtil.getTableFullName(stmt.getFunctionCall().getFunctionName().toString())); 10532 if (cursor != null) { 10533 TObjectName starColumn = new TObjectName(); 10534 starColumn.setString("*"); 10535 TableColumn insertColumn = modelFactory.createTableColumn(tableModel, starColumn, true); 10536 insertColumn.setShowStar(false); 10537 insertColumn.setExpandStar(true); 10538 for (int j = 0; j < cursor.getColumns().size(); j++) { 10539 DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation(); 10540 dataflowRelation.setEffectType(effectType); 10541 dataflowRelation.addSource(new TableColumnRelationshipElement(cursor.getColumns().get(j))); 10542 dataflowRelation.setTarget(new TableColumnRelationshipElement(insertColumn)); 10543 Process process = modelFactory.createProcess(stmt); 10544 dataflowRelation.setProcess(process); 10545 } 10546 } 10547 10548 } else if (stmt.getInsertSource() == EInsertSource.values && stmt.getValues() != null) { 10549 TObjectName starColumn = new TObjectName(); 10550 starColumn.setString("*"); 10551 TableColumn insertColumn = modelFactory.createTableColumn(tableModel, starColumn, true); 10552 insertColumn.setShowStar(false); 10553 insertColumn.setExpandStar(true); 10554 for (int k = 0; stmt.getValues() != null && k < stmt.getValues().size(); k++) { 10555 TResultColumnList columns = stmt.getValues().getMultiTarget(k).getColumnList(); 10556 for (int x = 0; x < columns.size(); x++) { 10557 TResultColumn columnObject = columns.getResultColumn(x); 10558 if (columnObject == null) { 10559 continue; 10560 } 10561 TExpression valueExpr = columnObject.getExpr(); 10562 columnsInExpr visitor = new columnsInExpr(); 10563 valueExpr.inOrderTraverse(visitor); 10564 List<TObjectName> objectNames = visitor.getObjectNames(); 10565 List<TParseTreeNode> constants = visitor.getConstants(); 10566 List<TParseTreeNode> functions = visitor.getFunctions(); 10567 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 10568 10569 Process process = modelFactory.createProcess(stmt); 10570 if (functions != null && !functions.isEmpty()) { 10571 analyzeFunctionDataFlowRelation(insertColumn, functions, effectType, process); 10572 } 10573 10574 if (subquerys != null && !subquerys.isEmpty()) { 10575 analyzeSubqueryDataFlowRelation(insertColumn, subquerys, effectType, process); 10576 } 10577 if (objectNames != null && !objectNames.isEmpty()) { 10578 analyzeDataFlowRelation(insertColumn, objectNames, null, effectType, functions, 10579 process); 10580 } 10581 //insert into values generate too many constant relations, ignore constant relations. 10582 if (constants != null && !constants.isEmpty() && stmt.getParentStmt() != null) { 10583 analyzeConstantDataFlowRelation(insertColumn, constants, effectType, functions, 10584 process); 10585 } 10586 } 10587 } 10588 }else if (stmt.getExecuteStmt() != null && stmt.getExecuteStmt().getModuleName() != null) { 10589 analyzeCustomSqlStmt(stmt.getExecuteStmt()); 10590 Procedure procedure = modelManager.getProcedureByName(DlineageUtil 10591 .getIdentifierNormalTableName(stmt.getExecuteStmt().getModuleName().toString())); 10592 if (procedure!=null && procedure.getProcedureObject() instanceof TStoredProcedureSqlStatement) { 10593 TStoredProcedureSqlStatement procedureStmt = (TStoredProcedureSqlStatement) procedure 10594 .getProcedureObject(); 10595 List<TSelectSqlStatement> stmtItems = getLastSelectStmt(procedureStmt); 10596 if (stmtItems != null) { 10597 for(TSelectSqlStatement stmtItem: stmtItems) { 10598 ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmtItem); 10599 if (resultSetModel != null) { 10600 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 10601 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 10602 10603 Transform transform = new Transform(); 10604 transform.setType(Transform.FUNCTION); 10605 transform.setCode(stmt.getExecuteStmt().getModuleName()); 10606 resultColumn.setTransform(transform); 10607 10608 TAliasClause alias = null; 10609 10610 if (resultColumn.getColumnObject() instanceof TResultColumn) { 10611 alias = ((TResultColumn) resultColumn.getColumnObject()) 10612 .getAliasClause(); 10613 } 10614 10615 if (alias != null && alias.getAliasName() != null) { 10616 TableColumn tableColumn; 10617 if (!initColumn) { 10618 if (tableModel.isCreateTable() 10619 && !containStarColumn(tableModel.getColumns())) { 10620 if(resultColumn.getName().endsWith("*")) { 10621 for(TableColumn tableColumnItem: tableModel.getColumns()) { 10622 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10623 relation.setEffectType(effectType); 10624 relation.setTarget(new TableColumnRelationshipElement(tableColumnItem)); 10625 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10626 Process process = modelFactory.createProcess(stmt); 10627 relation.setProcess(process); 10628 } 10629 continue; 10630 } 10631 else { 10632 if (tableModel.getColumns().size() <= i) { 10633 continue; 10634 } 10635 tableColumn = tableModel.getColumns().get(i); 10636 } 10637 } else { 10638 tableColumn = modelFactory.createInsertTableColumn(tableModel, 10639 alias.getAliasName()); 10640 } 10641 } else { 10642 tableColumn = matchColumn(tableColumns, alias.getAliasName()); 10643 if (tableColumn == null) { 10644 continue; 10645 } 10646 } 10647 10648 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10649 relation.setEffectType(effectType); 10650 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 10651 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10652 Process process = modelFactory.createProcess(stmt); 10653 relation.setProcess(process); 10654 } else if (resultColumn.getColumnObject() instanceof TObjectName 10655 || (resultColumn.getColumnObject() instanceof TResultColumn 10656 && ((TResultColumn) resultColumn.getColumnObject()) 10657 .getFieldAttr() != null)) { 10658 TObjectName fieldAttr = null; 10659 if (resultColumn.getColumnObject() instanceof TObjectName) { 10660 fieldAttr = (TObjectName) resultColumn.getColumnObject(); 10661 } else { 10662 fieldAttr = ((TResultColumn) resultColumn.getColumnObject()).getFieldAttr(); 10663 } 10664 TableColumn tableColumn; 10665 if (!initColumn) { 10666 if (tableModel.isCreateTable() 10667 && !containStarColumn(tableModel.getColumns())) { 10668 if(resultColumn.getName().endsWith("*")) { 10669 for(TableColumn tableColumnItem: tableModel.getColumns()) { 10670 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10671 relation.setEffectType(effectType); 10672 relation.setTarget(new TableColumnRelationshipElement(tableColumnItem)); 10673 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10674 Process process = modelFactory.createProcess(stmt); 10675 relation.setProcess(process); 10676 } 10677 continue; 10678 } 10679 else { 10680 if (tableModel.getColumns().size() <= i) { 10681 continue; 10682 } 10683 tableColumn = tableModel.getColumns().get(i); 10684 } 10685 } else { 10686 tableColumn = modelFactory.createInsertTableColumn(tableModel, 10687 fieldAttr); 10688 } 10689 } else { 10690 tableColumn = matchColumn(tableColumns, fieldAttr); 10691 if (tableColumn == null) { 10692 continue; 10693 } 10694 } 10695 10696 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10697 relation.setEffectType(effectType); 10698 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 10699 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10700 Process process = modelFactory.createProcess(stmt); 10701 relation.setProcess(process); 10702 } else if (((TResultColumn) resultColumn.getColumnObject()).getExpr() 10703 .getExpressionType() == EExpressionType.simple_constant_t) { 10704 if (!initColumn) { 10705 TableColumn tableColumn; 10706 if (tableModel.isCreateTable() 10707 && !containStarColumn(tableModel.getColumns())) { 10708 if(resultColumn.getName().endsWith("*")) { 10709 for(TableColumn tableColumnItem: tableModel.getColumns()) { 10710 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10711 relation.setEffectType(effectType); 10712 relation.setTarget(new TableColumnRelationshipElement(tableColumnItem)); 10713 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10714 Process process = modelFactory.createProcess(stmt); 10715 relation.setProcess(process); 10716 } 10717 continue; 10718 } 10719 else { 10720 if (tableModel.getColumns().size() <= i) { 10721 continue; 10722 } 10723 tableColumn = tableModel.getColumns().get(i); 10724 } 10725 } else { 10726 tableColumn = modelFactory.createInsertTableColumn(tableModel, 10727 ((TResultColumn) resultColumn.getColumnObject()).getExpr() 10728 .getConstantOperand(), 10729 i); 10730 } 10731 10732 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10733 relation.setEffectType(effectType); 10734 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 10735 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10736 Process process = modelFactory.createProcess(stmt); 10737 relation.setProcess(process); 10738 } 10739 } else { 10740 if (!initColumn) { 10741 TableColumn tableColumn; 10742 if (tableModel.isCreateTable() 10743 && !containStarColumn(tableModel.getColumns())) { 10744 if(resultColumn.getName().endsWith("*")) { 10745 for(TableColumn tableColumnItem: tableModel.getColumns()) { 10746 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10747 relation.setEffectType(effectType); 10748 relation.setTarget(new TableColumnRelationshipElement(tableColumnItem)); 10749 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10750 Process process = modelFactory.createProcess(stmt); 10751 relation.setProcess(process); 10752 } 10753 continue; 10754 } 10755 else { 10756 if (tableModel.getColumns().size() <= i) { 10757 continue; 10758 } 10759 tableColumn = tableModel.getColumns().get(i); 10760 } 10761 } else { 10762 tableColumn = modelFactory.createInsertTableColumn(tableModel, 10763 ((TResultColumn) resultColumn.getColumnObject()).getExpr(), 10764 i); 10765 } 10766 10767 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10768 relation.setEffectType(effectType); 10769 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 10770 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 10771 Process process = modelFactory.createProcess(stmt); 10772 relation.setProcess(process); 10773 } 10774 } 10775 } 10776 } 10777 } 10778 } 10779 } 10780 else if (procedure!=null && procedure.getProcedureObject() instanceof TObjectName) { 10781 TObjectName functionName = new TObjectName(); 10782 functionName.setString(procedure.getName()); 10783 Function function = (Function)createFunction(functionName); 10784 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 10785 relation.setEffectType(effectType); 10786 TObjectName starColumn = new TObjectName(); 10787 starColumn.setString("*"); 10788 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 10789 starColumn); 10790 tableColumn.setExpandStar(false); 10791 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 10792 relation.addSource(new ResultColumnRelationshipElement(function.getColumns().get(0))); 10793 Process process = modelFactory.createProcess(stmt); 10794 relation.setProcess(process); 10795 } 10796 } 10797 } 10798 10799 if(stmt.getOnDuplicateKeyUpdate()!=null) { 10800 TTable table = stmt.getTargetTable(); 10801 Table tableModel = modelFactory.createTable(table); 10802 for(TResultColumn column: stmt.getOnDuplicateKeyUpdate()) { 10803 if(column.getExpr()==null || column.getExpr().getExpressionType() != EExpressionType.assignment_t) { 10804 continue; 10805 } 10806 TExpression left = column.getExpr().getLeftOperand(); 10807 TExpression right = column.getExpr().getRightOperand(); 10808 TObjectName columnObject = left.getObjectOperand(); 10809 if (columnObject != null) { 10810 TableColumn tableColumn = modelFactory.createTableColumn(tableModel, columnObject, false); 10811 if (tableColumn != null) { 10812 columnsInExpr visitor = new columnsInExpr(); 10813 right.inOrderTraverse(visitor); 10814 List<TObjectName> objectNames = visitor.getObjectNames(); 10815 List<TParseTreeNode> functions = visitor.getFunctions(); 10816 List<TParseTreeNode> constants = visitor.getConstants(); 10817 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 10818 10819 if (functions != null && !functions.isEmpty()) { 10820 analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.update); 10821 } 10822 if (subquerys != null && !subquerys.isEmpty()) { 10823 analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.update); 10824 } 10825 if (objectNames != null && !objectNames.isEmpty()) { 10826 analyzeDataFlowRelation(tableColumn, objectNames, EffectType.update, functions); 10827 } 10828 if (constants != null && !constants.isEmpty()) { 10829 analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.update, functions); 10830 } 10831 } 10832 } 10833 } 10834 } 10835 10836 if (!expressions.isEmpty() && stmt.getSubQuery() != null) { 10837 analyzeInsertImpactRelation(stmt.getSubQuery(), tableColumnMap, expressions, effectType); 10838 } 10839 } 10840 10841 private List<TSelectSqlStatement> getLastSelectStmt(TStoredProcedureSqlStatement procedureStmt) { 10842 List<TSelectSqlStatement> stmts = new ArrayList<TSelectSqlStatement>(); 10843 if (procedureStmt.getBodyStatements().size() > 0) { 10844 for (int j = procedureStmt.getBodyStatements().size() - 1; j >= 0; j--) { 10845 TCustomSqlStatement stmtItem = procedureStmt.getBodyStatements().get(j); 10846 if (stmtItem instanceof TReturnStmt || stmtItem instanceof TMssqlReturn) { 10847 if (stmtItem.getStatements() != null) { 10848 List<TSelectSqlStatement> item = getLastSelectStmt(stmtItem); 10849 if (item != null && !item.isEmpty()) { 10850 stmts.addAll(item); 10851 if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) { 10852 break; 10853 } 10854 } 10855 } 10856 break; 10857 } 10858 if (stmtItem instanceof TSelectSqlStatement) { 10859 stmts.add((TSelectSqlStatement) stmtItem); 10860 if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) { 10861 break; 10862 } 10863 } else if (stmtItem.getStatements() != null) { 10864 List<TSelectSqlStatement> item = getLastSelectStmt(stmtItem); 10865 if (item != null && !item.isEmpty()) { 10866 stmts.addAll(item); 10867 if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) { 10868 break; 10869 } 10870 } 10871 } 10872 } 10873 } 10874 return stmts; 10875 } 10876 10877 private List<TSelectSqlStatement> getLastSelectStmt(TCustomSqlStatement stmt) { 10878 List<TSelectSqlStatement> stmts = new ArrayList<TSelectSqlStatement>(); 10879 for (int j = stmt.getStatements().size() - 1; j >= 0; j--) { 10880 TCustomSqlStatement stmtItem = stmt.getStatements().get(j); 10881 if (stmtItem instanceof TReturnStmt || stmtItem instanceof TMssqlReturn) { 10882 if (stmtItem.getStatements() != null) { 10883 List<TSelectSqlStatement> item = getLastSelectStmt(stmtItem); 10884 if (item != null && !item.isEmpty()) { 10885 stmts.addAll(item); 10886 if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) { 10887 break; 10888 } 10889 } 10890 } 10891 break; 10892 } 10893 if (stmtItem instanceof TSelectSqlStatement) { 10894 stmts.add((TSelectSqlStatement) stmtItem); 10895 if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) { 10896 break; 10897 } 10898 } else if (stmtItem.getStatements() != null) { 10899 List<TSelectSqlStatement> item = getLastSelectStmt(stmtItem); 10900 if (item != null && !item.isEmpty()) { 10901 stmts.addAll(item); 10902 if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) { 10903 break; 10904 } 10905 } 10906 } 10907 } 10908 return stmts; 10909 } 10910 10911 private TableColumn getStarColumn(List<TableColumn> columns) { 10912 for (TableColumn column : columns) { 10913 if (column.getName().endsWith("*")) { 10914 return column; 10915 } 10916 } 10917 return null; 10918 } 10919 10920 private boolean containStarColumn(List<TableColumn> columns) { 10921 if (columns == null) 10922 return false; 10923 for (TableColumn column : columns) { 10924 if (column.getName().endsWith("*")) { 10925 return true; 10926 } 10927 } 10928 return false; 10929 } 10930 10931 private boolean containStarColumn(ResultSet resultSet) { 10932 if (resultSet == null || resultSet.getColumns() == null) 10933 return false; 10934 for (ResultColumn column : resultSet.getColumns()) { 10935 if (column.getName().endsWith("*")) { 10936 return true; 10937 } 10938 } 10939 return false; 10940 } 10941 10942 private int indexOfColumn(List<TResultColumn> columns, TObjectName objectName) { 10943 for (int i = 0; i < columns.size(); i++) { 10944 if (columns.get(i).toString().trim().equalsIgnoreCase(objectName.toString().trim())) { 10945 return i; 10946 } 10947 } 10948 return -1; 10949 } 10950 10951 private boolean isEmptyCollection(Collection<?> keyMap) { 10952 return keyMap == null || keyMap.isEmpty(); 10953 } 10954 10955 private void analyzeInsertImpactRelation(TSelectSqlStatement stmt, Map<String, List<TableColumn>> insertMap, 10956 List<TExpression> expressions, EffectType effectType) { 10957 List<TObjectName> objectNames = new ArrayList<TObjectName>(); 10958 for (int i = 0; i < expressions.size(); i++) { 10959 TExpression condition = expressions.get(i); 10960 columnsInExpr visitor = new columnsInExpr(); 10961 condition.inOrderTraverse(visitor); 10962 objectNames.addAll(visitor.getObjectNames()); 10963 } 10964 10965 Iterator<String> iter = insertMap.keySet().iterator(); 10966 while (iter.hasNext()) { 10967 String table = iter.next(); 10968 List<TableColumn> tableColumns = insertMap.get(table); 10969 for (int i = 0; i < tableColumns.size(); i++) { 10970 10971 TableColumn column = tableColumns.get(i); 10972 ImpactRelationship relation = modelFactory.createImpactRelation(); 10973 relation.setEffectType(effectType); 10974 relation.setTarget(new TableColumnRelationshipElement(column)); 10975 10976 for (int j = 0; j < objectNames.size(); j++) { 10977 TObjectName columnName = objectNames.get(j); 10978 Object model = modelManager.getModel(stmt); 10979 if (model instanceof SelectResultSet) { 10980 SelectResultSet queryTable = (SelectResultSet) model; 10981 List<ResultColumn> columns = queryTable.getColumns(); 10982 for (int k = 0; k < columns.size(); k++) { 10983 ResultColumn resultColumn = columns.get(k); 10984 if (resultColumn.getAlias() != null 10985 && columnName.toString().equalsIgnoreCase(resultColumn.getAlias())) { 10986 relation.addSource( 10987 new ResultColumnRelationshipElement(resultColumn, columnName.getLocation())); 10988 } else if (resultColumn.getName() != null 10989 && columnName.toString().equalsIgnoreCase(resultColumn.getName())) { 10990 relation.addSource( 10991 new ResultColumnRelationshipElement(resultColumn, columnName.getLocation())); 10992 } 10993 } 10994 } 10995 } 10996 } 10997 } 10998 } 10999 11000 private void analyzeUpdateStmt(TUpdateSqlStatement stmt) { 11001 if (stmt.getResultColumnList() == null) 11002 return; 11003 11004 TTable table = stmt.getTargetTable(); 11005 while (table.getCTE() != null || table.getSubquery() != null || (table.getLinkTable() != null && table.getLinkTable().getSubquery() != null)) { 11006 if (table.getCTE() != null) { 11007 table = table.getCTE().getSubquery().getTables().getTable(0); 11008 } else if (table.getLinkTable() != null && table.getLinkTable().getSubquery() != null) { 11009 table = table.getLinkTable().getSubquery().getTables().getTable(0); 11010 } else if (table.getSubquery() != null) { 11011 table = table.getSubquery().getTables().getTable(0); 11012 } 11013 } 11014 Table tableModel = modelFactory.createTable(table); 11015 Process process = modelFactory.createProcess(stmt); 11016 tableModel.addProcess(process); 11017 11018 for (int i = 0; i < stmt.tables.size(); i++) { 11019 TTable tableElement = stmt.tables.getTable(i); 11020 if (tableElement.getSubquery() != null) { 11021 QueryTable queryTable = modelFactory.createQueryTable(tableElement); 11022 TSelectSqlStatement subquery = tableElement.getSubquery(); 11023 analyzeSelectStmt(subquery); 11024 11025 if (subquery.getSetOperatorType() != ESetOperatorType.none) { 11026 SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager.getModel(subquery); 11027 for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) { 11028 ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j); 11029 ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn); 11030 DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation(); 11031 selectSetRalation.setEffectType(EffectType.select); 11032 selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 11033 selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 11034 selectSetRalation.setProcess(process); 11035 } 11036 } 11037 11038 ResultSet resultSetModel = (ResultSet) modelManager.getModel(tableElement.getSubquery()); 11039 if (resultSetModel != null && resultSetModel != queryTable 11040 && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 11041 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 11042 impactRelation.setEffectType(EffectType.update); 11043 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 11044 resultSetModel.getRelationRows())); 11045 impactRelation.setTarget( 11046 new RelationRowsRelationshipElement<ResultSetRelationRows>(queryTable.getRelationRows())); 11047 } 11048 11049 } else if (tableElement.getCTE() != null) { 11050 QueryTable queryTable = modelFactory.createQueryTable(tableElement); 11051 11052 TObjectNameList cteColumns = tableElement.getCTE().getColumnList(); 11053 if (cteColumns != null) { 11054 for (int j = 0; j < cteColumns.size(); j++) { 11055 modelFactory.createResultColumn(queryTable, cteColumns.getObjectName(j)); 11056 } 11057 } 11058 TSelectSqlStatement subquery = tableElement.getCTE().getSubquery(); 11059 if (subquery != null && !stmtStack.contains(subquery)) { 11060 analyzeSelectStmt(subquery); 11061 11062 ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery); 11063 if (resultSetModel != null && resultSetModel != queryTable 11064 && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 11065 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 11066 impactRelation.setEffectType(EffectType.select); 11067 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 11068 resultSetModel.getRelationRows())); 11069 impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 11070 queryTable.getRelationRows())); 11071 } 11072 11073 if (subquery.getSetOperatorType() != ESetOperatorType.none) { 11074 SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager 11075 .getModel(subquery); 11076 for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) { 11077 ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j); 11078 ResultColumn targetColumn = null; 11079 if (cteColumns != null) { 11080 targetColumn = queryTable.getColumns().get(j); 11081 } else { 11082 targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn); 11083 } 11084 for (Set<TObjectName> starLinkColumns : sourceColumn.getStarLinkColumns().values()) { 11085 for (TObjectName starLinkColumn : starLinkColumns) { 11086 targetColumn.bindStarLinkColumn(starLinkColumn); 11087 } 11088 } 11089 DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation(); 11090 selectSetRalation.setEffectType(EffectType.select); 11091 selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 11092 selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 11093 selectSetRalation.setProcess(process); 11094 } 11095 } else { 11096 for (int j = 0; j < resultSetModel.getColumns().size(); j++) { 11097 ResultColumn sourceColumn = resultSetModel.getColumns().get(j); 11098 ResultColumn targetColumn = null; 11099 if (cteColumns != null) { 11100 targetColumn = queryTable.getColumns().get(j); 11101 } else { 11102 targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn); 11103 } 11104 for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) { 11105 targetColumn.bindStarLinkColumn(starLinkColumn); 11106 } 11107 DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation(); 11108 selectSetRalation.setEffectType(EffectType.select); 11109 selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 11110 selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 11111 selectSetRalation.setProcess(process); 11112 } 11113 } 11114 } else if (tableElement.getCTE().getUpdateStmt() != null) { 11115 analyzeCustomSqlStmt(tableElement.getCTE().getUpdateStmt()); 11116 } else if (tableElement.getCTE().getInsertStmt() != null) { 11117 analyzeCustomSqlStmt(tableElement.getCTE().getInsertStmt()); 11118 } else if (tableElement.getCTE().getDeleteStmt() != null) { 11119 analyzeCustomSqlStmt(tableElement.getCTE().getDeleteStmt()); 11120 } 11121 } else { 11122 modelFactory.createTable(stmt.tables.getTable(i)); 11123 } 11124 } 11125 11126 for (int i = 0; i < stmt.getResultColumnList().size(); i++) { 11127 TResultColumn field = stmt.getResultColumnList().getResultColumn(i); 11128 11129 if (field.getExpr().getExpressionType() == EExpressionType.function_t) { 11130 // Handle SQL Server XML modify() method for data lineage 11131 TFunctionCall funcCall = field.getExpr().getFunctionCall(); 11132 if (funcCall != null && funcCall.getFunctionType() == EFunctionType.xmlmodify_t) { 11133 analyzeXmlModifyFunction(stmt, tableModel, process, funcCall); 11134 } 11135 continue; 11136 } 11137 11138 TExpression expression = field.getExpr().getLeftOperand(); 11139 if (expression == null) { 11140 ErrorInfo errorInfo = new ErrorInfo(); 11141 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 11142 errorInfo.setErrorMessage( 11143 "Can't get result column expression. Expression is " + field.getExpr().toString()); 11144 errorInfo.setStartPosition(new Pair3<Long, Long, String>(field.getExpr().getStartToken().lineNo, 11145 field.getExpr().getStartToken().columnNo, ModelBindingManager.getGlobalHash())); 11146 errorInfo.setEndPosition(new Pair3<Long, Long, String>(field.getExpr().getEndToken().lineNo, 11147 field.getExpr().getEndToken().columnNo + field.getExpr().getEndToken().getAstext().length(), 11148 ModelBindingManager.getGlobalHash())); 11149 errorInfo.fillInfo(this); 11150 errorInfos.add(errorInfo); 11151 continue; 11152 } 11153 if (expression.getExpressionType() == EExpressionType.list_t) { 11154 TExpression setExpression = field.getExpr().getRightOperand(); 11155 if (setExpression != null && setExpression.getSubQuery() != null) { 11156 TSelectSqlStatement query = setExpression.getSubQuery(); 11157 analyzeSelectStmt(query); 11158 11159 SelectResultSet resultSetModel = (SelectResultSet) modelManager 11160 .getModel(query.getResultColumnList()); 11161 11162 if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 11163 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 11164 impactRelation.setEffectType(EffectType.update); 11165 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 11166 resultSetModel.getRelationRows())); 11167 impactRelation.setTarget( 11168 new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows())); 11169 } 11170 11171 TExpressionList columnList = expression.getExprList(); 11172 for (int j = 0; j < columnList.size(); j++) { 11173 TObjectName column = columnList.getExpression(j).getObjectOperand(); 11174 11175 if (column.getDbObjectType() == EDbObjectType.variable) { 11176 continue; 11177 } 11178 11179 if (column.getColumnNameOnly().startsWith("@") && (option.getVendor() == EDbVendor.dbvmssql 11180 || option.getVendor() == EDbVendor.dbvazuresql)) { 11181 continue; 11182 } 11183 11184 if (column.getColumnNameOnly().startsWith(":") && (option.getVendor() == EDbVendor.dbvhana 11185 || option.getVendor() == EDbVendor.dbvteradata)) { 11186 continue; 11187 } 11188 11189 ResultColumn resultColumn = resultSetModel.getColumns().get(j); 11190 TableColumn tableColumn = modelFactory.createTableColumn(tableModel, column, false); 11191 if (tableColumn != null) { 11192 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11193 relation.setEffectType(EffectType.update); 11194 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 11195 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 11196 relation.setProcess(process); 11197 } 11198 11199 } 11200 } 11201 } else if (expression.getExpressionType() == EExpressionType.simple_object_name_t) { 11202 TExpression setExpression = field.getExpr().getRightOperand(); 11203 if (setExpression != null && setExpression.getSubQuery() != null) { 11204 TSelectSqlStatement query = setExpression.getSubQuery(); 11205 analyzeSelectStmt(query); 11206 11207 SelectResultSet resultSetModel = (SelectResultSet) modelManager 11208 .getModel(query.getResultColumnList()); 11209 11210 if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 11211 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 11212 impactRelation.setEffectType(EffectType.update); 11213 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 11214 resultSetModel.getRelationRows())); 11215 impactRelation.setTarget( 11216 new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows())); 11217 } 11218 11219 TObjectName column = expression.getObjectOperand(); 11220 ResultColumn resultColumn = resultSetModel.getColumns().get(0); 11221 TableColumn tableColumn = modelFactory.createTableColumn(tableModel, column, false); 11222 if (tableColumn != null) { 11223 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11224 relation.setEffectType(EffectType.update); 11225 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 11226 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 11227 relation.setProcess(process); 11228 } 11229 } else if (setExpression != null) { 11230 // ResultSet resultSet = modelFactory.createResultSet(stmt, 11231 // true); 11232 11233 ResultSet resultSet = modelFactory.createResultSet(stmt, false); 11234 11235 createPseudoImpactRelation(stmt, resultSet, EffectType.update); 11236 11237 TObjectName columnObject = expression.getObjectOperand(); 11238 11239 ResultColumn updateColumn = modelFactory.createUpdateResultColumn(resultSet, columnObject); 11240 11241 columnsInExpr visitor = new columnsInExpr(); 11242 field.getExpr().getRightOperand().inOrderTraverse(visitor); 11243 11244 List<TObjectName> objectNames = visitor.getObjectNames(); 11245 List<TParseTreeNode> functions = visitor.getFunctions(); 11246 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 11247 11248 if (functions != null && !functions.isEmpty()) { 11249 analyzeFunctionDataFlowRelation(updateColumn, functions, EffectType.update); 11250 } 11251 11252 if (subquerys != null && !subquerys.isEmpty()) { 11253 analyzeSubqueryDataFlowRelation(updateColumn, subquerys, EffectType.update); 11254 } 11255 11256 Transform transform = new Transform(); 11257 transform.setType(Transform.EXPRESSION); 11258 transform.setCode(setExpression); 11259 updateColumn.setTransform(transform); 11260 analyzeDataFlowRelation(updateColumn, objectNames, EffectType.update, functions); 11261 11262 List<TParseTreeNode> constants = visitor.getConstants(); 11263 analyzeConstantDataFlowRelation(updateColumn, constants, EffectType.update, functions); 11264 11265 TableColumn tableColumn = modelFactory.createTableColumn(tableModel, columnObject, false); 11266 if(tableColumn!=null) { 11267 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11268 relation.setEffectType(EffectType.update); 11269 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 11270 relation.addSource(new ResultColumnRelationshipElement(updateColumn)); 11271 relation.setProcess(process); 11272 } 11273 11274 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 11275 impactRelation.setEffectType(EffectType.update); 11276 impactRelation.addSource( 11277 new RelationRowsRelationshipElement<ResultSetRelationRows>(resultSet.getRelationRows())); 11278 impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>( 11279 tableModel.getRelationRows())); 11280 } 11281 } 11282 } 11283 11284 if (stmt.getJoins() != null && stmt.getJoins().size() > 0) { 11285 for (int i = 0; i < stmt.getJoins().size(); i++) { 11286 TJoin join = stmt.getJoins().getJoin(i); 11287 if (join.getJoinItems() != null) { 11288 for (int j = 0; j < join.getJoinItems().size(); j++) { 11289 TJoinItem joinItem = join.getJoinItems().getJoinItem(j); 11290 TExpression expr = joinItem.getOnCondition(); 11291 analyzeFilterCondition(null, expr, joinItem.getJoinType(), JoinClauseType.on, 11292 EffectType.update); 11293 } 11294 } 11295 } 11296 } 11297 11298 if (stmt.getWhereClause() != null && stmt.getWhereClause().getCondition() != null) { 11299 analyzeFilterCondition(null, stmt.getWhereClause().getCondition(), null, JoinClauseType.where, 11300 EffectType.update); 11301 } 11302 11303 if (stmt.getOutputClause() != null) { 11304 TOutputClause outputClause = stmt.getOutputClause(); 11305 if (outputClause.getSelectItemList() != null) { 11306 ResultSet resultSet = modelFactory.createResultSet(outputClause, false); 11307 for (int j = 0; j < outputClause.getSelectItemList().size(); j++) { 11308 TResultColumn sourceColumn = outputClause.getSelectItemList().getResultColumn(j); 11309 ResultColumn sourceColumnModel = modelFactory.createResultColumn(resultSet, sourceColumn); 11310 analyzeResultColumn(sourceColumn, EffectType.select); 11311 11312 if (outputClause.getIntoTable() != null) { 11313 Table intoTableModel = modelFactory.createTableByName(outputClause.getIntoTable()); 11314 intoTableModel.addProcess(process); 11315 if (outputClause.getIntoColumnList() != null) { 11316 TableColumn intoTableColumn = modelFactory.createInsertTableColumn(intoTableModel, 11317 outputClause.getIntoColumnList().getObjectName(j)); 11318 11319 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11320 relation.setEffectType(EffectType.insert); 11321 relation.setTarget(new TableColumnRelationshipElement(intoTableColumn)); 11322 relation.addSource(new ResultColumnRelationshipElement(sourceColumnModel)); 11323 } else if (sourceColumn.getAliasClause() != null 11324 || sourceColumn.getExpr().getObjectOperand() != null) { 11325 TObjectName tableColumnObject = null; 11326 if (sourceColumn.getAliasClause() != null) { 11327 tableColumnObject = sourceColumn.getAliasClause().getAliasName(); 11328 } else { 11329 tableColumnObject = sourceColumn.getExpr().getObjectOperand(); 11330 } 11331 11332 TableColumn intoTableColumn = modelFactory.createInsertTableColumn(intoTableModel, 11333 tableColumnObject); 11334 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11335 relation.setEffectType(EffectType.insert); 11336 relation.setTarget(new TableColumnRelationshipElement(intoTableColumn)); 11337 relation.addSource(new ResultColumnRelationshipElement(sourceColumnModel)); 11338 } 11339 } 11340 } 11341 } 11342 } 11343 } 11344 11345 /** 11346 * Analyzes SQL Server XML modify() function to extract data lineage from sql:column() references 11347 * in XQuery expressions. 11348 * 11349 * Example SQL: 11350 * SET [Demographics].modify('... sql:column("deleted.LineTotal") ...') 11351 * 11352 * This extracts: 11353 * - Target column: Demographics (from the XML column being modified) 11354 * - Source column: deleted.LineTotal (from sql:column() reference in XQuery) 11355 */ 11356 private void analyzeXmlModifyFunction(TUpdateSqlStatement stmt, Table tableModel, Process process, TFunctionCall funcCall) { 11357 TObjectName funcName = funcCall.getFunctionName(); 11358 if (funcName == null || funcName.getPartToken() == null) { 11359 return; 11360 } 11361 11362 // Get the XML column being modified (e.g., [Demographics] from "[Demographics].modify") 11363 String xmlColumnName = funcName.getPartToken().astext; 11364 11365 // Get the XQuery argument 11366 if (funcCall.getArgs() == null || funcCall.getArgs().size() == 0) { 11367 return; 11368 } 11369 11370 String xqueryString = funcCall.getArgs().getExpression(0).toString(); 11371 11372 // Extract sql:column() references from the XQuery string 11373 List<String> sqlColumnRefs = extractSqlColumnReferences(xqueryString); 11374 if (sqlColumnRefs.isEmpty()) { 11375 return; 11376 } 11377 11378 // Extract XPath target from XQuery (e.g., /IndividualSurvey/TotalPurchaseYTD) 11379 String xpathTarget = extractXPathTarget(xqueryString); 11380 11381 // Build full target column name including XML path 11382 String fullTargetColumnName = xmlColumnName; 11383 if (xpathTarget != null && !xpathTarget.isEmpty()) { 11384 fullTargetColumnName = xmlColumnName + "." + xpathTarget; 11385 } 11386 11387 // Create the target table column for the XML column being modified 11388 TableColumn targetTableColumn = modelFactory.createInsertTableColumn(tableModel, fullTargetColumnName); 11389 11390 // Create source-to-target relationships for each sql:column reference 11391 for (String sqlColRef : sqlColumnRefs) { 11392 // Parse the column reference (e.g., "deleted.LineTotal" -> table="deleted", column="LineTotal") 11393 String[] parts = sqlColRef.split("\\.", 2); 11394 String sourceTableName = parts.length > 1 ? parts[0] : null; 11395 String sourceColumnName = parts.length > 1 ? parts[1] : parts[0]; 11396 11397 // Find the source table in the statement's tables 11398 TTable sourceTable = null; 11399 if (sourceTableName != null && stmt.tables != null) { 11400 for (int j = 0; j < stmt.tables.size(); j++) { 11401 TTable t = stmt.tables.getTable(j); 11402 String tableName = t.getTableName().toString(); 11403 String alias = t.getAliasName(); 11404 if (tableName.equalsIgnoreCase(sourceTableName) || 11405 (alias != null && alias.equalsIgnoreCase(sourceTableName))) { 11406 sourceTable = t; 11407 break; 11408 } 11409 } 11410 } 11411 11412 if (sourceTable != null && targetTableColumn != null) { 11413 // Create a table model for the source if needed 11414 Table sourceTableModel = modelFactory.createTable(sourceTable); 11415 TableColumn sourceColumn = modelFactory.createInsertTableColumn(sourceTableModel, sourceColumnName); 11416 11417 if (sourceColumn != null) { 11418 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11419 relation.setEffectType(EffectType.update); 11420 relation.setTarget(new TableColumnRelationshipElement(targetTableColumn)); 11421 relation.addSource(new TableColumnRelationshipElement(sourceColumn)); 11422 relation.setProcess(process); 11423 relation.setFunction("modify"); 11424 } 11425 } 11426 } 11427 } 11428 11429 /** 11430 * Extracts sql:column() references from an XQuery string. 11431 * Example: 'sql:column("deleted.LineTotal")' -> ["deleted.LineTotal"] 11432 */ 11433 private List<String> extractSqlColumnReferences(String xquery) { 11434 List<String> refs = new ArrayList<>(); 11435 if (xquery == null) { 11436 return refs; 11437 } 11438 11439 int startIdx = 0; 11440 while ((startIdx = xquery.indexOf("sql:column(", startIdx)) >= 0) { 11441 int parenStart = startIdx + "sql:column(".length(); 11442 int parenEnd = xquery.indexOf(")", parenStart); 11443 if (parenEnd < 0) { 11444 break; 11445 } 11446 11447 String arg = xquery.substring(parenStart, parenEnd).trim(); 11448 // Remove quotes (single or double) 11449 if ((arg.startsWith("\"") && arg.endsWith("\"")) || 11450 (arg.startsWith("'") && arg.endsWith("'"))) { 11451 arg = arg.substring(1, arg.length() - 1); 11452 } 11453 11454 if (!arg.isEmpty()) { 11455 refs.add(arg); 11456 } 11457 11458 startIdx = parenEnd + 1; 11459 } 11460 11461 return refs; 11462 } 11463 11464 /** 11465 * Extracts the XPath target from an XQuery modify expression. 11466 * Example: 'replace value of (/IndividualSurvey/TotalPurchaseYTD)[1]' -> "IndividualSurvey.TotalPurchaseYTD" 11467 */ 11468 private String extractXPathTarget(String xquery) { 11469 if (xquery == null) { 11470 return null; 11471 } 11472 11473 // Look for patterns like "(/path/to/element)" or "(/path/to/element)[1]" 11474 int replaceIdx = xquery.indexOf("replace value of"); 11475 if (replaceIdx < 0) { 11476 return null; 11477 } 11478 11479 int parenStart = xquery.indexOf("(/", replaceIdx); 11480 if (parenStart < 0) { 11481 return null; 11482 } 11483 11484 int parenEnd = xquery.indexOf(")", parenStart); 11485 if (parenEnd < 0) { 11486 return null; 11487 } 11488 11489 String xpath = xquery.substring(parenStart + 1, parenEnd); 11490 // Remove any predicates like [1] 11491 int bracketIdx = xpath.indexOf("["); 11492 if (bracketIdx > 0) { 11493 xpath = xpath.substring(0, bracketIdx); 11494 } 11495 11496 // Convert XPath to dot notation (e.g., /IndividualSurvey/TotalPurchaseYTD -> IndividualSurvey.TotalPurchaseYTD) 11497 if (xpath.startsWith("/")) { 11498 xpath = xpath.substring(1); 11499 } 11500 xpath = xpath.replace("/", "."); 11501 11502 return xpath; 11503 } 11504 11505 private void analyzeConstantDataFlowRelation(Object modelObject, List<TParseTreeNode> constants, 11506 EffectType effectType, List<TParseTreeNode> functions) { 11507 analyzeConstantDataFlowRelation(modelObject, constants, effectType, functions, null); 11508 } 11509 11510 private void analyzeConstantDataFlowRelation(Object modelObject, List<TParseTreeNode> constants, 11511 EffectType effectType, List<TParseTreeNode> functions, Process process) { 11512 if (constants == null || constants.size() == 0) 11513 return; 11514 11515 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11516 relation.setEffectType(effectType); 11517 relation.setProcess(process); 11518 11519 if (functions != null && !functions.isEmpty()) { 11520 relation.setFunction(getFunctionName(functions.get(0))); 11521 } 11522 11523 if (modelObject instanceof ResultColumn) { 11524 relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) modelObject)); 11525 11526 } else if (modelObject instanceof TableColumn) { 11527 relation.setTarget(new TableColumnRelationshipElement((TableColumn) modelObject)); 11528 11529 } else { 11530 throw new UnsupportedOperationException(); 11531 } 11532 11533 if (option.isShowConstantTable()) { 11534 Table constantTable = null; 11535 if(modelObject instanceof FunctionResultColumn && ((FunctionResultColumn)modelObject).getFunction() instanceof TFunctionCall) { 11536 TFunctionCall function = (TFunctionCall)((FunctionResultColumn)modelObject).getFunction(); 11537 if(function.getFunctionType() == EFunctionType.struct_t) { 11538 constantTable = modelFactory.createConstantsTable(String.valueOf(function.toString().hashCode())); 11539 } 11540 } 11541 if(constantTable == null) { 11542 constantTable = modelFactory.createConstantsTable(stmtStack.peek()); 11543 } 11544 for (int i = 0; i < constants.size(); i++) { 11545 TParseTreeNode constant = constants.get(i); 11546 if (constant instanceof TConstant) { 11547 TableColumn constantColumn = modelFactory.createTableColumn(constantTable, (TConstant) constant); 11548 relation.addSource(new ConstantRelationshipElement(constantColumn)); 11549 } else if (constant instanceof TObjectName) { 11550 TableColumn constantColumn = modelFactory.createTableColumn(constantTable, (TObjectName) constant, 11551 false); 11552 if(constantColumn == null) { 11553 continue; 11554 } 11555 relation.addSource(new ConstantRelationshipElement(constantColumn)); 11556 } 11557 } 11558 } 11559 11560 } 11561 11562 private String getFunctionName(TParseTreeNode parseTreeNode) { 11563 if (parseTreeNode instanceof TFunctionCall) { 11564 return ((TFunctionCall) parseTreeNode).getFunctionName().toString(); 11565 } 11566 if (parseTreeNode instanceof TCaseExpression) { 11567 return "case-when"; 11568 } 11569 return null; 11570 } 11571 11572 private void analyzeCreateViewStmt(TCustomSqlStatement stmt, TSelectSqlStatement subquery, 11573 TViewAliasClause viewAlias, TObjectName viewName) { 11574 11575 if (subquery != null) { 11576 TTableList tables = subquery.getTables(); 11577 if (tables != null) { 11578 for (int i = 0; i < tables.size(); i++) { 11579 TTable table = tables.getTable(i); 11580 TCustomSqlStatement createView = viewDDLMap 11581 .get(DlineageUtil.getTableFullName(table.getTableName().toString())); 11582 if (createView != null) { 11583 analyzeCustomSqlStmt(createView); 11584 } 11585 } 11586 } 11587 analyzeSelectStmt(subquery); 11588 } 11589 11590 11591 if (viewAlias != null && viewAlias.getViewAliasItemList() != null) { 11592 TViewAliasItemList viewItems = viewAlias.getViewAliasItemList(); 11593 Table viewModel = modelFactory.createView(stmt, viewName, true); 11594 viewModel.setFromDDL(true); 11595 viewModel.setDetermined(true); 11596 Process process = modelFactory.createProcess(stmt); 11597 viewModel.addProcess(process); 11598 ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery); 11599 if (resultSetModel != null) { 11600 int resultSetSize = resultSetModel.getColumns().size(); 11601 int viewItemSize = viewItems.size(); 11602 int j = 0; 11603 int viewColumnSize = viewItemSize; 11604 if (resultSetModel.isDetermined() && resultSetSize > viewColumnSize) { 11605 viewColumnSize = resultSetSize; 11606 } 11607 for (int i = 0; i < viewColumnSize && j < resultSetSize; i++) { 11608 ResultColumn resultColumn = resultSetModel.getColumns().get(j); 11609 if (i < viewItemSize) { 11610 TObjectName alias = viewItems.getViewAliasItem(i).getAlias(); 11611 11612 if (!resultSetModel.getColumns().get(j).getName().contains("*")) { 11613 j++; 11614 } else { 11615 if (resultSetSize - j == viewItems.size() - i) { 11616 j++; 11617 } 11618 } 11619 11620 if (alias != null) { 11621 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, alias, i, true); 11622 appendTableColumnToSQLEnv(viewModel, viewColumn); 11623 if (resultColumn != null) { 11624 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11625 relation.setEffectType(EffectType.create_view); 11626 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11627 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 11628 relation.setProcess(process); 11629 } 11630 } else if (resultColumn.getColumnObject() instanceof TObjectName) { 11631 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, 11632 (TObjectName) resultColumn.getColumnObject(), i, true); 11633 appendTableColumnToSQLEnv(viewModel, viewColumn); 11634 if (resultColumn != null) { 11635 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11636 relation.setEffectType(EffectType.create_view); 11637 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11638 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 11639 relation.setProcess(process); 11640 } 11641 } else if (resultColumn.getColumnObject() instanceof TResultColumn) { 11642 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, 11643 ((TResultColumn) resultColumn.getColumnObject()).getFieldAttr(), i, true); 11644 appendTableColumnToSQLEnv(viewModel, viewColumn); 11645 ResultColumn column = (ResultColumn) modelManager.getModel(resultColumn.getColumnObject()); 11646 if (column != null && !column.getStarLinkColumns().isEmpty()) { 11647 viewColumn.bindStarLinkColumns(column.getStarLinkColumns()); 11648 } 11649 if (resultColumn != null) { 11650 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11651 relation.setEffectType(EffectType.create_view); 11652 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11653 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 11654 relation.setProcess(process); 11655 } 11656 } 11657 } 11658 else if(resultSetModel.isDetermined()){ 11659 TObjectName viewColumnName = new TObjectName(); 11660 viewColumnName.setString(resultColumn.getName()); 11661 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, viewColumnName, viewModel.getColumns().size(), true); 11662 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11663 relation.setEffectType(EffectType.create_view); 11664 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11665 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 11666 relation.setProcess(process); 11667 j++; 11668 } 11669 } 11670 if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 11671 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 11672 impactRelation.setEffectType(EffectType.create_view); 11673 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 11674 resultSetModel.getRelationRows())); 11675 impactRelation.setTarget( 11676 new RelationRowsRelationshipElement<TableRelationRows>(viewModel.getRelationRows())); 11677 } 11678 } 11679 11680 if (subquery.getResultColumnList() == null && subquery.getValueClause() != null 11681 && subquery.getValueClause().getValueRows().size() == viewItems.size()) { 11682 for (int i = 0; i < viewItems.size(); i++) { 11683 TObjectName alias = viewItems.getViewAliasItem(i).getAlias(); 11684 11685 if (alias != null) { 11686 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, alias, i, true); 11687 appendTableColumnToSQLEnv(viewModel, viewColumn); 11688 TExpression expression = subquery.getValueClause().getValueRows().getValueRowItem(i).getExpr(); 11689 11690 columnsInExpr visitor = new columnsInExpr(); 11691 expression.inOrderTraverse(visitor); 11692 List<TObjectName> objectNames = visitor.getObjectNames(); 11693 List<TParseTreeNode> functions = visitor.getFunctions(); 11694 11695 if (functions != null && !functions.isEmpty()) { 11696 analyzeFunctionDataFlowRelation(viewColumn, functions, EffectType.select); 11697 11698 } 11699 11700 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 11701 if (subquerys != null && !subquerys.isEmpty()) { 11702 analyzeSubqueryDataFlowRelation(viewColumn, subquerys, EffectType.select); 11703 } 11704 11705 analyzeDataFlowRelation(viewColumn, objectNames, EffectType.select, functions); 11706 List<TParseTreeNode> constants = visitor.getConstants(); 11707 analyzeConstantDataFlowRelation(viewColumn, constants, EffectType.select, functions); 11708 } 11709 } 11710 } 11711 11712 } else { 11713 if (viewName == null) { 11714 ErrorInfo errorInfo = new ErrorInfo(); 11715 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 11716 errorInfo.setErrorMessage("Can't get view name. CreateView is " + stmt.toString()); 11717 errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo, 11718 stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash())); 11719 errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo, 11720 stmt.getEndToken().columnNo + stmt.getEndToken().getAstext().length(), 11721 ModelBindingManager.getGlobalHash())); 11722 errorInfo.fillInfo(this); 11723 errorInfos.add(errorInfo); 11724 return; 11725 } 11726 Table viewModel = modelFactory.createView(stmt, viewName); 11727 Process process = modelFactory.createProcess(stmt); 11728 viewModel.addProcess(process); 11729 if (subquery != null && !subquery.isCombinedQuery()) { 11730 SelectResultSet resultSetModel = (SelectResultSet) modelManager 11731 .getModel(subquery.getResultColumnList()); 11732 11733 boolean determined = false; 11734 if (!containStarColumn(resultSetModel)) { 11735 viewModel.setCreateTable(true); 11736 determined = true; 11737 viewModel.setFromDDL(true); 11738 } 11739 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 11740 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 11741 if (resultColumn.getColumnObject() instanceof TResultColumn) { 11742 TResultColumn columnObject = ((TResultColumn) resultColumn.getColumnObject()); 11743 11744 TAliasClause alias = ((TResultColumn) resultColumn.getColumnObject()).getAliasClause(); 11745 if (alias != null && alias.getAliasName() != null) { 11746 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, alias.getAliasName(), i, 11747 determined); 11748 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11749 relation.setEffectType(EffectType.create_view); 11750 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11751 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 11752 relation.setProcess(process); 11753 if (determined) { 11754 appendTableColumnToSQLEnv(viewModel, viewColumn); 11755 } 11756 } else if (columnObject.getFieldAttr() != null) { 11757 TObjectName viewColumnObject = columnObject.getFieldAttr(); 11758 TableColumn viewColumn; 11759 Object model = modelManager.getModel(resultColumn.getColumnObject()); 11760 if ("*".equals(viewColumnObject.getColumnNameOnly())) { 11761 if (model instanceof LinkedHashMap) { 11762 String columnName = getColumnNameOnly(resultColumn.getName()); 11763 LinkedHashMap<String, ResultColumn> resultColumns = (LinkedHashMap<String, ResultColumn>) model; 11764 if ("*".equals(columnName)) { 11765 for (String key : resultColumns.keySet()) { 11766 ResultColumn column = resultColumns.get(key); 11767 viewColumn = modelFactory.createInsertTableColumn(viewModel, column.getName()); 11768 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11769 relation.setEffectType(EffectType.create_view); 11770 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11771 relation.addSource(new ResultColumnRelationshipElement(column)); 11772 relation.setProcess(process); 11773 } 11774 continue; 11775 } else if (resultColumns.containsKey(columnName)) { 11776 ResultColumn column = resultColumns.get(columnName); 11777 viewColumn = modelFactory.createInsertTableColumn(viewModel, column.getName()); 11778 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11779 relation.setEffectType(EffectType.create_view); 11780 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11781 relation.addSource(new ResultColumnRelationshipElement(column)); 11782 relation.setProcess(process); 11783 continue; 11784 } 11785 } 11786 } 11787 11788 if (!SQLUtil.isEmpty(viewColumnObject.getColumnNameOnly()) 11789 && viewColumnObject.getPropertyToken() != null) { 11790 TObjectName object = new TObjectName(); 11791 // object.setString(viewColumnObject.getPropertyToken().astext); 11792 object.setPartToken(viewColumnObject.getPropertyToken()); 11793 object.setStartToken(viewColumnObject.getPropertyToken()); 11794 object.setEndToken(viewColumnObject.getPropertyToken()); 11795 viewColumn = modelFactory.createViewColumn(viewModel, object, i, determined); 11796 } else { 11797 viewColumn = modelFactory.createViewColumn(viewModel, columnObject.getFieldAttr(), 11798 i, determined); 11799 } 11800 11801 if(determined) { 11802 appendTableColumnToSQLEnv(viewModel, viewColumn); 11803 } 11804 11805 if (model instanceof ResultColumn) { 11806 ResultColumn column = (ResultColumn) modelManager 11807 .getModel(resultColumn.getColumnObject()); 11808 if (column != null && !column.getStarLinkColumns().isEmpty()) { 11809 viewColumn.bindStarLinkColumns(column.getStarLinkColumns()); 11810 } 11811 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11812 relation.setEffectType(EffectType.create_view); 11813 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11814 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 11815 if (sqlenv == null) { 11816 if (resultColumn.isShowStar()) { 11817 relation.setShowStarRelation(true); 11818 viewColumn.setShowStar(true); 11819 resultColumn.setShowStar(true); 11820 setSourceShowStar(resultColumn); 11821 } 11822 } 11823 if (viewColumn.getName().endsWith("*") && resultColumn.getName().endsWith("*")) { 11824 viewModel.setStarStmt("create_view"); 11825 } 11826 relation.setProcess(process); 11827 } 11828 } else if (resultColumn.getAlias() != null && columnObject.getExpr() 11829 .getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) { 11830 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, 11831 columnObject.getExpr().getLeftOperand().getObjectOperand(), i, determined); 11832 if(determined) { 11833 appendTableColumnToSQLEnv(viewModel, viewColumn); 11834 } 11835 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11836 relation.setEffectType(EffectType.create_view); 11837 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11838 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 11839 relation.setProcess(process); 11840 } else { 11841 TGSqlParser parser = columnObject.getGsqlparser(); 11842 TObjectName viewColumnName = parser 11843 .parseObjectName(generateQuotedName(parser, columnObject.toString())); 11844 if (viewColumnName == null) { 11845 ErrorInfo errorInfo = new ErrorInfo(); 11846 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 11847 errorInfo.setErrorMessage( 11848 "Can't parse view column. Column is " + columnObject.toString()); 11849 errorInfo.setStartPosition(new Pair3<Long, Long, String>( 11850 columnObject.getStartToken().lineNo, columnObject.getStartToken().columnNo, 11851 ModelBindingManager.getGlobalHash())); 11852 errorInfo 11853 .setEndPosition(new Pair3<Long, Long, String>(columnObject.getEndToken().lineNo, 11854 columnObject.getEndToken().columnNo 11855 + columnObject.getEndToken().getAstext().length(), 11856 ModelBindingManager.getGlobalHash())); 11857 errorInfo.fillInfo(this); 11858 errorInfos.add(errorInfo); 11859 } else { 11860 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, viewColumnName, i, 11861 determined); 11862 if(determined) { 11863 appendTableColumnToSQLEnv(viewModel, viewColumn); 11864 } 11865 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11866 relation.setEffectType(EffectType.create_view); 11867 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11868 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 11869 relation.setProcess(process); 11870 } 11871 } 11872 } else if (resultColumn.getColumnObject() instanceof TObjectName) { 11873 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, 11874 (TObjectName) resultColumn.getColumnObject(), i, determined); 11875 if(determined) { 11876 appendTableColumnToSQLEnv(viewModel, viewColumn); 11877 } 11878 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11879 relation.setEffectType(EffectType.create_view); 11880 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11881 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 11882 relation.setProcess(process); 11883 } 11884 } 11885 if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 11886 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 11887 impactRelation.setEffectType(EffectType.create_view); 11888 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 11889 resultSetModel.getRelationRows())); 11890 impactRelation.setTarget( 11891 new RelationRowsRelationshipElement<TableRelationRows>(viewModel.getRelationRows())); 11892 } 11893 } else if (subquery != null && subquery.isCombinedQuery()) { 11894 SelectSetResultSet resultSetModel = (SelectSetResultSet) modelManager.getModel(subquery); 11895 11896 boolean determined = false; 11897 if (!containStarColumn(resultSetModel)) { 11898 viewModel.setCreateTable(true); 11899 viewModel.setFromDDL(true); 11900 determined = true; 11901 } 11902 11903 for (int i = 0; i < resultSetModel.getColumns().size(); i++) { 11904 ResultColumn resultColumn = resultSetModel.getColumns().get(i); 11905 11906 if (resultColumn.getColumnObject() instanceof TResultColumn) { 11907 TResultColumn columnObject = ((TResultColumn) resultColumn.getColumnObject()); 11908 11909 TAliasClause alias = columnObject.getAliasClause(); 11910 if (alias != null && alias.getAliasName() != null) { 11911 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, alias.getAliasName(), i, 11912 determined); 11913 if(determined) { 11914 appendTableColumnToSQLEnv(viewModel, viewColumn); 11915 } 11916 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11917 relation.setEffectType(EffectType.create_view); 11918 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11919 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 11920 relation.setProcess(process); 11921 } else if (columnObject.getFieldAttr() != null) { 11922 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, 11923 columnObject.getFieldAttr(), i, determined); 11924 if(determined) { 11925 appendTableColumnToSQLEnv(viewModel, viewColumn); 11926 } 11927 ResultColumn column = (ResultColumn) modelManager.getModel(resultColumn.getColumnObject()); 11928 if (column != null && !column.getStarLinkColumns().isEmpty()) { 11929 viewColumn.bindStarLinkColumns(column.getStarLinkColumns()); 11930 } 11931 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11932 relation.setEffectType(EffectType.create_view); 11933 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11934 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 11935 relation.setProcess(process); 11936 } else if (resultColumn.getAlias() != null && columnObject.getExpr() 11937 .getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) { 11938 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, 11939 columnObject.getExpr().getLeftOperand().getObjectOperand(), i, determined); 11940 if(determined) { 11941 appendTableColumnToSQLEnv(viewModel, viewColumn); 11942 } 11943 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11944 relation.setEffectType(EffectType.create_view); 11945 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11946 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 11947 relation.setProcess(process); 11948 } else { 11949 TGSqlParser parser = columnObject.getGsqlparser(); 11950 TObjectName viewColumnName = parser 11951 .parseObjectName(generateQuotedName(parser, columnObject.toString())); 11952 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, viewColumnName, i, 11953 determined); 11954 if(determined) { 11955 appendTableColumnToSQLEnv(viewModel, viewColumn); 11956 } 11957 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11958 relation.setEffectType(EffectType.create_view); 11959 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11960 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 11961 relation.setProcess(process); 11962 } 11963 } else if (resultColumn.getColumnObject() instanceof TObjectName) { 11964 TableColumn viewColumn = modelFactory.createViewColumn(viewModel, 11965 (TObjectName) resultColumn.getColumnObject(), i, determined); 11966 if(viewColumn!=null) { 11967 if(determined) { 11968 appendTableColumnToSQLEnv(viewModel, viewColumn); 11969 } 11970 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 11971 relation.setEffectType(EffectType.create_view); 11972 relation.setTarget(new ViewColumnRelationshipElement(viewColumn)); 11973 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 11974 relation.setProcess(process); 11975 } 11976 } 11977 } 11978 if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 11979 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 11980 impactRelation.setEffectType(EffectType.create_view); 11981 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 11982 resultSetModel.getRelationRows())); 11983 impactRelation.setTarget( 11984 new RelationRowsRelationshipElement<TableRelationRows>(viewModel.getRelationRows())); 11985 } 11986 } 11987 } 11988 } 11989 11990 private void setSourceShowStar(Object resultColumn) { 11991 for (Relationship relation : modelManager.getRelations()) { 11992 Collection<RelationshipElement<?>> sources = (Collection<RelationshipElement<?>>)relation.getSources(); 11993 if (relation.getTarget().getElement() == resultColumn && sources != null) { 11994 11995 ((AbstractRelationship) relation).setShowStarRelation(true); 11996 for (RelationshipElement<?> source : sources) { 11997 Object column = source.getElement(); 11998 if (column instanceof TableColumn) { 11999 if (((TableColumn) column).isShowStar()) 12000 continue; 12001 ((TableColumn) column).setShowStar(true); 12002 } 12003 if (column instanceof ResultColumn) { 12004 if (((ResultColumn) column).isShowStar()) 12005 continue; 12006 ((ResultColumn) column).setShowStar(true); 12007 } 12008 setSourceShowStar(column); 12009 } 12010 } 12011 } 12012 } 12013 12014 private String generateQuotedName(TGSqlParser parser, String name) { 12015 return "\"" + name + "\""; 12016 } 12017 12018 private void appendRelations(dataflow dataflow) { 12019 Relationship[] relations = modelManager.getRelations(); 12020 12021 appendRelation(dataflow, relations, DataFlowRelationship.class); 12022 appendRelation(dataflow, relations, IndirectImpactRelationship.class); 12023 appendRecordSetRelation(dataflow, relations); 12024 appendCallRelation(dataflow, relations); 12025 appendRelation(dataflow, relations, ImpactRelationship.class); 12026 appendRelation(dataflow, relations, JoinRelationship.class); 12027 appendRelation(dataflow, relations, ERRelationship.class); 12028 appendRelation(dataflow, relations, CrudRelationship.class); 12029 } 12030 12031 12032 private relationship cloneRelationshipWithSingleSource(relationship orig, sourceColumn src) { 12033 relationship rel = new relationship(); 12034 rel.setType(orig.getType()); 12035 rel.setEffectType(orig.getEffectType()); 12036 rel.setId(orig.getId() + "_" + src.getColumn()); 12037 rel.setSqlHash(orig.getSqlHash()); 12038 rel.setSqlComment(orig.getSqlComment()); 12039 rel.setProcessId(orig.getProcessId()); 12040 rel.setProcessType(orig.getProcessType()); 12041 rel.setFunction(orig.getFunction()); 12042 rel.setProcedureId(orig.getProcedureId()); 12043 12044 targetColumn t = new targetColumn(); 12045 t.setId(orig.getTarget().getId()); 12046 t.setColumn(orig.getTarget().getColumn()); 12047 t.setParent_id(orig.getTarget().getParent_id()); 12048 t.setParent_name(orig.getTarget().getParent_name()); 12049 t.setParent_alias(orig.getTarget().getParent_alias()); 12050 t.setCoordinate(orig.getTarget().getCoordinate()); 12051 rel.setTarget(t); 12052 12053 sourceColumn s = new sourceColumn(); 12054 s.setId(src.getId()); 12055 s.setColumn(src.getColumn()); 12056 s.setParent_id(src.getParent_id()); 12057 s.setParent_name(src.getParent_name()); 12058 s.setCoordinate(src.getCoordinate()); 12059 rel.addSource(s); 12060 return rel; 12061 } 12062 12063 private Set<String> appendStarColumns = new HashSet<String>(); 12064 private void appendRelation(dataflow dataflow, Relationship[] relations, Class<? extends Relationship> clazz) { 12065 for (int i = 0; i < relations.length; i++) { 12066 AbstractRelationship relation = (AbstractRelationship) relations[i]; 12067 if (relation.getClass() == clazz) { 12068 if (relation.getSources() == null || relation.getTarget() == null) { 12069 continue; 12070 } 12071 Object targetElement = relation.getTarget().getElement(); 12072 TObjectName targetColumnName = null; 12073 if(relation.getTarget() instanceof ResultColumnRelationshipElement) { 12074 targetColumnName = ((ResultColumnRelationshipElement) relation.getTarget()).getColumnName(); 12075 } 12076 if (targetElement instanceof ResultColumn) { 12077 ResultColumn targetColumn = (ResultColumn) targetElement; 12078 if (!targetColumn.isPseduo()) 12079 { 12080 if (targetColumnName == null) 12081 { 12082 if ("*".equals(targetColumn.getName())) { 12083 updateResultColumnStarLinks(dataflow, relation, -1); 12084 } 12085 12086 if (targetColumn.hasStarLinkColumn()) { 12087 for (int j = 0; j < targetColumn.getStarLinkColumnNames().size(); j++) { 12088 appendStarRelation(dataflow, relation, j); 12089 } 12090 12091 if (!containsStar(relation.getSources())) { 12092 continue; 12093 } 12094 } 12095 } 12096 else { 12097 String columnName = DlineageUtil.getColumnName(targetColumnName); 12098 int index = targetColumn.getStarLinkColumnNames().indexOf(columnName); 12099 if (index != -1) { 12100 int size = targetColumn.getStarLinkColumnNames().size(); 12101 if ("*".equals(targetColumn.getName())) { 12102 if (appendStarColumns.contains(columnName)) { 12103 updateResultColumnStarLinks(dataflow, relation, index); 12104 } 12105 else { 12106 updateResultColumnStarLinks(dataflow, relation, -1); 12107 appendStarColumns.add(columnName); 12108 } 12109 } 12110 appendStarRelation(dataflow, relation, index); 12111 for(int j= size; j < targetColumn.getStarLinkColumnNames().size(); j++) { 12112 appendStarRelation(dataflow, relation, j); 12113 } 12114 if (!containsStar(relation.getSources())) { 12115 continue; 12116 } 12117 } 12118 } 12119 } 12120 } else if (targetElement instanceof TableColumn) { 12121 TableColumn targetColumn = (TableColumn) targetElement; 12122 if (!targetColumn.isPseduo()) { 12123 if ("*".equals(targetColumn.getName())) { 12124 updateTableColumnStarLinks(dataflow, relation); 12125 } 12126 12127 if (targetColumn.hasStarLinkColumn() && !targetColumn.isVariant() 12128 && targetColumn.isExpandStar()) { 12129 for (int j = 0; j < targetColumn.getStarLinkColumnNames().size(); j++) { 12130 appendStarRelation(dataflow, relation, j); 12131 } 12132 if (!containsStar(relation.getSources())) { 12133 continue; 12134 } 12135 } 12136 } 12137 } 12138 12139 relationship relationElement = new relationship(); 12140 relationElement.setType(relation.getRelationshipType().name()); 12141 if (relation.getEffectType() != null) { 12142 relationElement.setEffectType(relation.getEffectType().name()); 12143 } 12144 if (relation.getFunction() != null) { 12145 relationElement.setFunction(relation.getFunction()); 12146 } 12147 relationElement.setSqlHash(relation.getSqlHash()); 12148 relationElement.setSqlComment(relation.getSqlComment()); 12149 12150 if (relation.getProcedureId() != null) { 12151 relationElement.setProcedureId(String.valueOf(relation.getProcedureId())); 12152 } 12153 relationElement.setId(String.valueOf(relation.getId())); 12154 if (relation.getProcess() != null) { 12155 relationElement.setProcessId(String.valueOf(relation.getProcess().getId())); 12156 if (relation.getProcess().getGspObject() != null) { 12157 relationElement.setProcessType(relation.getProcess().getGspObject().sqlstatementtype.name()); 12158 } 12159 } 12160 12161 if (relation.getPartition() != null) { 12162 relationElement.setPartition(relation.getPartition()); 12163 } 12164 relationElement.setSqlHash(relation.getSqlHash()); 12165 relationElement.setSqlComment(relation.getSqlComment()); 12166 12167 if (relation.getProcedureId() != null) { 12168 relationElement.setProcedureId(String.valueOf(relation.getProcedureId())); 12169 } 12170 12171 if (relation instanceof JoinRelationship) { 12172 relationElement.setCondition(((JoinRelationship) relation).getJoinCondition()); 12173 relationElement.setJoinType(((JoinRelationship) relation).getJoinType().name()); 12174 relationElement.setClause(((JoinRelationship) relation).getJoinClauseType().name()); 12175 } 12176 12177 if(relation instanceof ImpactRelationship){ 12178 ImpactRelationship impactRelationship = (ImpactRelationship)relation; 12179 if(impactRelationship.getJoinClauseType()!=null){ 12180 relationElement.setClause(impactRelationship.getJoinClauseType().name()); 12181 } 12182 } 12183 12184 String targetName = null; 12185 Object columnObject = null; 12186 List<TObjectName> targetObjectNames = null; 12187 12188 if (targetElement instanceof ResultSetRelationRows) { 12189 ResultSetRelationRows targetColumn = (ResultSetRelationRows) targetElement; 12190 targetColumn target = new targetColumn(); 12191 target.setId(String.valueOf(targetColumn.getId())); 12192 target.setColumn(targetColumn.getName()); 12193 target.setParent_id(String.valueOf(targetColumn.getHolder().getId())); 12194 target.setParent_name(getResultSetName(targetColumn.getHolder())); 12195 if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) { 12196 target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + "," 12197 + convertCoordinate(targetColumn.getEndPosition())); 12198 } 12199 if (relation instanceof RecordSetRelationship) { 12200 target.setFunction(((RecordSetRelationship) relation).getAggregateFunction()); 12201 } 12202 target.setSource("system"); 12203 targetName = targetColumn.getName(); 12204 relationElement.setTarget(target); 12205 } else if (targetElement instanceof TableRelationRows) { 12206 TableRelationRows targetColumn = (TableRelationRows) targetElement; 12207 targetColumn target = new targetColumn(); 12208 target.setId(String.valueOf(targetColumn.getId())); 12209 target.setColumn(targetColumn.getName()); 12210 target.setParent_id(String.valueOf(targetColumn.getHolder().getId())); 12211 target.setParent_name(getTableName(targetColumn.getHolder())); 12212 if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) { 12213 target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + "," 12214 + convertCoordinate(targetColumn.getEndPosition())); 12215 } 12216 if (relation instanceof RecordSetRelationship) { 12217 target.setFunction(((RecordSetRelationship) relation).getAggregateFunction()); 12218 } 12219 target.setSource("system"); 12220 targetName = targetColumn.getName(); 12221 relationElement.setTarget(target); 12222 } else if (targetElement instanceof ResultColumn) { 12223 ResultColumn targetColumn = (ResultColumn) targetElement; 12224 targetColumn target = new targetColumn(); 12225 target.setId(String.valueOf(targetColumn.getId())); 12226 target.setColumn(targetColumn.getName()); 12227 target.setStruct(targetColumn.isStruct()); 12228 target.setParent_id(String.valueOf(targetColumn.getResultSet().getId())); 12229 target.setParent_name(getResultSetName(targetColumn.getResultSet())); 12230 if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) { 12231 target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + "," 12232 + convertCoordinate(targetColumn.getEndPosition())); 12233 } 12234 if (relation instanceof RecordSetRelationship) { 12235 target.setFunction(((RecordSetRelationship) relation).getAggregateFunction()); 12236 } 12237 targetName = targetColumn.getName(); 12238 if (((ResultColumn) targetColumn).getColumnObject() instanceof TResultColumn) { 12239 columnsInExpr visitor = new columnsInExpr(); 12240 ((TResultColumn) ((ResultColumn) targetColumn).getColumnObject()).getExpr() 12241 .inOrderTraverse(visitor); 12242 targetObjectNames = visitor.getObjectNames(); 12243 } 12244 12245 if (targetElement instanceof FunctionResultColumn) { 12246 columnObject = ((FunctionResultColumn) targetElement).getColumnObject(); 12247 } 12248 if(targetColumn.isPseduo()) { 12249 target.setSource("system"); 12250 } 12251 relationElement.setTarget(target); 12252 } else if (targetElement instanceof TableColumn) { 12253 TableColumn targetColumn = (TableColumn) targetElement; 12254 targetColumn target = new targetColumn(); 12255 target.setId(String.valueOf(targetColumn.getId())); 12256 target.setColumn(targetColumn.getName()); 12257 target.setStruct(targetColumn.isStruct()); 12258 target.setParent_id(String.valueOf(targetColumn.getTable().getId())); 12259 target.setParent_name(getTableName(targetColumn.getTable())); 12260 if (relation.getTarget() instanceof TableColumnRelationshipElement) { 12261 target.setParent_alias(((TableColumnRelationshipElement) relation.getTarget()).getTableAlias()); 12262 } 12263 if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) { 12264 target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + "," 12265 + convertCoordinate(targetColumn.getEndPosition())); 12266 } 12267 if (relation instanceof RecordSetRelationship) { 12268 target.setFunction(((RecordSetRelationship) relation).getAggregateFunction()); 12269 } 12270 if(targetColumn.isPseduo()) { 12271 target.setSource("system"); 12272 } 12273 targetName = targetColumn.getName(); 12274 relationElement.setTarget(target); 12275 } else if (targetElement instanceof Argument) { 12276 Argument targetColumn = (Argument) targetElement; 12277 targetColumn target = new targetColumn(); 12278 target.setId(String.valueOf(targetColumn.getId())); 12279 target.setColumn(targetColumn.getName()); 12280 target.setParent_id(String.valueOf(targetColumn.getProcedure().getId())); 12281 target.setParent_name(targetColumn.getProcedure().getName()); 12282 if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) { 12283 target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + "," 12284 + convertCoordinate(targetColumn.getEndPosition())); 12285 } 12286 if (relation instanceof RecordSetRelationship) { 12287 target.setFunction(((RecordSetRelationship) relation).getAggregateFunction()); 12288 } 12289 targetName = targetColumn.getName(); 12290 relationElement.setTarget(target); 12291 } else if (targetElement instanceof Table) { 12292 Table table = (Table) targetElement; 12293 targetColumn target = new targetColumn(); 12294 target.setTarget_id(String.valueOf(table.getId())); 12295 target.setTarget_name(getTableName(table)); 12296 if (table.getStartPosition() != null && table.getEndPosition() != null) { 12297 target.setCoordinate(convertCoordinate(table.getStartPosition()) + "," 12298 + convertCoordinate(table.getEndPosition())); 12299 } 12300 relationElement.setTarget(target); 12301 } else { 12302 continue; 12303 } 12304 12305 Collection<RelationshipElement<?>> sourceElements = relation.getSources(); 12306 if (sourceElements.size() == 0) { 12307 if(clazz == CrudRelationship.class && option.getAnalyzeMode() == AnalyzeMode.crud) { 12308 dataflow.getRelationships().add(relationElement); 12309 } 12310 continue; 12311 } 12312 12313 boolean append = false; 12314 for (RelationshipElement<?> sourceItem: relation.getSources()) { 12315 Object sourceElement = sourceItem.getElement(); 12316 TObjectName sourceColumnName = null; 12317 if (sourceItem instanceof ResultColumnRelationshipElement) { 12318 sourceColumnName = ((ResultColumnRelationshipElement) sourceItem).getColumnName(); 12319 } 12320// if (sourceItem instanceof TableColumnRelationElement 12321// && (((TableColumnRelationElement) sourceItem).getColumnIndex() != null)) { 12322// TableColumnRelationElement tableColumnRelationElement = (TableColumnRelationElement) sourceItem; 12323// sourceElement = tableColumnRelationElement.getElement().getTable().getColumns() 12324// .get(tableColumnRelationElement.getColumnIndex() + 1); 12325// } 12326 if (sourceElement instanceof ResultColumn) { 12327 ResultColumn sourceColumn = (ResultColumn) sourceElement; 12328 if (sourceColumn.hasStarLinkColumn() && !relation.isShowStarRelation() && !sourceColumn.isPseduo()) { 12329 List<String> sourceStarColumnNames = sourceColumn.getStarLinkColumnNames(); 12330 sourceColumn source = new sourceColumn(); 12331 if (targetObjectNames != null && !targetObjectNames.isEmpty()) { 12332 12333 for (int k = 0; k < targetObjectNames.size(); k++) { 12334 String targetObjectName = getColumnName(targetObjectNames.get(k)); 12335 if(sourceColumn.getResultSet()!=null && sourceColumn.getResultSet().getColumns()!=null) { 12336 boolean find = false; 12337 for(ResultColumn column: sourceColumn.getResultSet().getColumns()) { 12338 if(column.getName().equalsIgnoreCase(targetObjectName)) { 12339 source = new sourceColumn(); 12340 source.setId(String.valueOf(column.getId())); 12341 source.setColumn(targetObjectName); 12342 source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId())); 12343 source.setParent_name(getResultSetName(sourceColumn.getResultSet())); 12344 if (sourceColumn.getStartPosition() != null 12345 && sourceColumn.getEndPosition() != null) { 12346 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) 12347 + "," + convertCoordinate(sourceColumn.getEndPosition())); 12348 } 12349 append = true; 12350 relationElement.addSource(source); 12351 find = true; 12352 break; 12353 } 12354 } 12355 if(find) { 12356 continue; 12357 } 12358 } 12359 if (sourceColumn.getStarLinkColumns().containsKey(targetObjectName)) { 12360 source = new sourceColumn(); 12361 source.setId(String.valueOf(sourceColumn.getId()) + "_" 12362 + sourceStarColumnNames.indexOf(targetObjectName)); 12363 source.setColumn(targetObjectName); 12364 source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId())); 12365 source.setParent_name(getResultSetName(sourceColumn.getResultSet())); 12366 if (sourceColumn.getStartPosition() != null 12367 && sourceColumn.getEndPosition() != null) { 12368 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) 12369 + "," + convertCoordinate(sourceColumn.getEndPosition())); 12370 } 12371 append = true; 12372 relationElement.addSource(source); 12373 } else { 12374 source = new sourceColumn(); 12375 source.setId(String.valueOf(sourceColumn.getId())); 12376 source.setColumn(relationElement.getTarget().getColumn()); 12377 source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId())); 12378 source.setParent_name(getResultSetName(sourceColumn.getResultSet())); 12379 if (sourceColumn.getStartPosition() != null 12380 && sourceColumn.getEndPosition() != null) { 12381 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) 12382 + "," + convertCoordinate(sourceColumn.getEndPosition())); 12383 } 12384 append = true; 12385 relationElement.addSource(source); 12386 } 12387 } 12388 } else { 12389 if (columnObject instanceof TWhenClauseItemList) { 12390 TCaseExpression expr = (TCaseExpression)((FunctionResultColumn) targetElement).getResultSet().getGspObject(); 12391 List<TExpression> directExpressions = new ArrayList<TExpression>(); 12392 12393// TExpression inputExpr = expr.getInput_expr(); 12394// if (inputExpr != null) { 12395// directExpressions.add(inputExpr); 12396// } 12397 TExpression defaultExpr = expr.getElse_expr(); 12398 if (defaultExpr != null) { 12399 directExpressions.add(defaultExpr); 12400 } 12401 TWhenClauseItemList list = expr.getWhenClauseItemList(); 12402 for (int k = 0; k < list.size(); k++) { 12403 TWhenClauseItem element = list.getWhenClauseItem(k); 12404 directExpressions.add(element.getReturn_expr()); 12405 } 12406 12407 for (int k = 0; k < directExpressions.size(); k++) { 12408 columnsInExpr visitor = new columnsInExpr(); 12409 directExpressions.get(k).inOrderTraverse(visitor); 12410 List<TObjectName> objectNames = visitor.getObjectNames(); 12411 if (objectNames == null) { 12412 continue; 12413 } 12414 for (int x = 0; x < objectNames.size(); x++) { 12415 String objectName = getColumnName(objectNames.get(x)); 12416 if (sourceColumn.getStarLinkColumns().containsKey(objectName)) { 12417 12418 if(sourceColumn.getResultSet()!=null && sourceColumn.getResultSet().getColumns()!=null) { 12419 boolean find = false; 12420 for(ResultColumn column: sourceColumn.getResultSet().getColumns()) { 12421 if(column.getName().equalsIgnoreCase(objectName)) { 12422 source = new sourceColumn(); 12423 source.setId(String.valueOf(column.getId())); 12424 source.setColumn(objectName); 12425 source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId())); 12426 source.setParent_name(getResultSetName(sourceColumn.getResultSet())); 12427 if (sourceColumn.getStartPosition() != null 12428 && sourceColumn.getEndPosition() != null) { 12429 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) 12430 + "," + convertCoordinate(sourceColumn.getEndPosition())); 12431 } 12432 append = true; 12433 relationElement.addSource(source); 12434 find = true; 12435 break; 12436 } 12437 } 12438 if(find) { 12439 continue; 12440 } 12441 } 12442 12443 source.setId(String.valueOf(sourceColumn.getId()) + "_" 12444 + sourceStarColumnNames.indexOf(objectName)); 12445 source.setColumn(objectName); 12446 } else { 12447 source.setId(String.valueOf(sourceColumn.getId())); 12448 source.setColumn(sourceColumn.getName()); 12449 } 12450 source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId())); 12451 source.setParent_name(getResultSetName(sourceColumn.getResultSet())); 12452 if (sourceColumn.getStartPosition() != null 12453 && sourceColumn.getEndPosition() != null) { 12454 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) 12455 + "," + convertCoordinate(sourceColumn.getEndPosition())); 12456 } 12457 append = true; 12458 relationElement.addSource(source); 12459 } 12460 } 12461 } else { 12462 String objectName = getColumnName(targetName); 12463 boolean find = false; 12464 12465 if (!find && sourceColumn.getStarLinkColumns().containsKey(objectName)) { 12466 source.setId(String.valueOf(sourceColumn.getId()) + "_" 12467 + sourceStarColumnNames.indexOf(objectName)); 12468 source.setColumn(objectName); 12469 find = true; 12470 } 12471 12472 if (!find && sourceColumnName != null) { 12473 objectName = getColumnName(sourceColumnName); 12474 12475 if(sourceColumn.getResultSet()!=null && sourceColumn.getResultSet().getColumns()!=null) { 12476 for(ResultColumn column: sourceColumn.getResultSet().getColumns()) { 12477 if(column.getName().equalsIgnoreCase(objectName)) { 12478 source = new sourceColumn(); 12479 source.setId(String.valueOf(column.getId())); 12480 source.setColumn(objectName); 12481 source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId())); 12482 source.setParent_name(getResultSetName(sourceColumn.getResultSet())); 12483 if (sourceColumn.getStartPosition() != null 12484 && sourceColumn.getEndPosition() != null) { 12485 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) 12486 + "," + convertCoordinate(sourceColumn.getEndPosition())); 12487 } 12488 append = true; 12489 relationElement.addSource(source); 12490 find = true; 12491 break; 12492 } 12493 } 12494 if(find) { 12495 continue; 12496 } 12497 } 12498 12499 if (sourceColumn.getStarLinkColumns().containsKey(objectName)) { 12500 source.setId(String.valueOf(sourceColumn.getId()) + "_" 12501 + sourceStarColumnNames.indexOf(objectName)); 12502 source.setColumn(objectName); 12503 find = true; 12504 } 12505 } 12506 12507 if (!find && sourceItem instanceof ResultColumnRelationshipElement) { 12508 int starIndex = ((ResultColumnRelationshipElement) sourceItem) 12509 .getStarIndex(); 12510 if (starIndex > -1 && sourceColumn.getStarLinkColumnList().size() > starIndex) { 12511 objectName = getColumnName(sourceColumn.getStarLinkColumnList().get(starIndex)); 12512 source.setId(String.valueOf(sourceColumn.getId()) + "_" 12513 + starIndex); 12514 source.setColumn(objectName); 12515 find = true; 12516 } 12517 } 12518 12519 if (!find) { 12520 source.setId(String.valueOf(sourceColumn.getId())); 12521 source.setColumn(sourceColumn.getName()); 12522 } 12523 12524 source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId())); 12525 source.setParent_name(getResultSetName(sourceColumn.getResultSet())); 12526 if (sourceColumn.getStartPosition() != null 12527 && sourceColumn.getEndPosition() != null) { 12528 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 12529 + convertCoordinate(sourceColumn.getEndPosition())); 12530 } 12531 append = true; 12532 relationElement.addSource(source); 12533 } 12534 } 12535 12536 } else { 12537 sourceColumn source = new sourceColumn(); 12538 source.setId(String.valueOf(sourceColumn.getId())); 12539 source.setColumn(sourceColumn.getName()); 12540 source.setStruct(sourceColumn.isStruct()); 12541 source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId())); 12542 source.setParent_name(getResultSetName(sourceColumn.getResultSet())); 12543 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 12544 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 12545 + convertCoordinate(sourceColumn.getEndPosition())); 12546 } 12547 append = true; 12548 if (sourceItem.getTransforms() != null) { 12549 for (Transform transform : sourceItem.getTransforms()) { 12550 source.addTransform(transform); 12551 } 12552 } 12553 if(sourceColumn.isPseduo()) { 12554 source.setSource("system"); 12555 } 12556 relationElement.addSource(source); 12557 } 12558 } else if (sourceElement instanceof TableColumn) { 12559 TableColumn sourceColumn = (TableColumn) sourceElement; 12560 if (!sourceColumn.isPseduo() && sourceColumn.hasStarLinkColumn() 12561 && sourceItem instanceof TableColumnRelationshipElement) { 12562 sourceColumn source = new sourceColumn(); 12563 boolean find = false; 12564 if (((TableColumnRelationshipElement) sourceItem).getColumnIndex() != null) { 12565 int columnIndex = ((TableColumnRelationshipElement) sourceItem).getColumnIndex(); 12566 if (sourceColumn.getStarLinkColumns().size() > columnIndex) { 12567 source = new sourceColumn(); 12568 source.setId(String.valueOf(sourceColumn.getId()) + "_" + columnIndex); 12569 String targetObjectName = getColumnName( 12570 sourceColumn.getStarLinkColumnList().get(columnIndex)); 12571 source.setColumn(targetObjectName); 12572 source.setParent_id(String.valueOf(sourceColumn.getTable().getId())); 12573 source.setParent_name(sourceColumn.getTable().getName()); 12574 if (sourceItem instanceof TableColumnRelationshipElement) { 12575 source.setParent_alias( 12576 ((TableColumnRelationshipElement) sourceItem).getTableAlias()); 12577 } 12578 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 12579 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 12580 + convertCoordinate(sourceColumn.getEndPosition())); 12581 } 12582 append = true; 12583 relationElement.addSource(source); 12584 find = true; 12585 } 12586 } 12587 12588 if (!find) { 12589 String objectName = getColumnName(targetName); 12590 12591 table tableElement = null; 12592 if (dataflow.getTables() != null) { 12593 for (table t : dataflow.getTables()) { 12594 if (t.getId().equals(String.valueOf(sourceColumn.getTable().getId()))) { 12595 tableElement = t; 12596 break; 12597 } 12598 } 12599 } 12600 if (tableElement == null && dataflow.getViews() != null) { 12601 for (table t : dataflow.getViews()) { 12602 if (t.getId().equals(String.valueOf(sourceColumn.getTable().getId()))) { 12603 tableElement = t; 12604 break; 12605 } 12606 } 12607 } 12608 if (tableElement == null && dataflow.getVariables() != null) { 12609 for (table t : dataflow.getVariables()) { 12610 if (t.getId().equals(String.valueOf(sourceColumn.getTable().getId()))) { 12611 tableElement = t; 12612 break; 12613 } 12614 } 12615 } 12616 12617 if(tableElement!=null) { 12618 for (column column : tableElement.getColumns()) { 12619 if (column.getName() != null && column.getName().equalsIgnoreCase(objectName)) { 12620 source = new sourceColumn(); 12621 source.setId(String.valueOf(column.getId())); 12622 source.setColumn(objectName); 12623 source.setParent_id(String.valueOf(sourceColumn.getTable().getId())); 12624 source.setParent_name(sourceColumn.getTable().getName()); 12625 if (sourceItem instanceof TableColumnRelationshipElement) { 12626 source.setParent_alias( 12627 ((TableColumnRelationshipElement) sourceItem).getTableAlias()); 12628 } 12629 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 12630 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 12631 + convertCoordinate(sourceColumn.getEndPosition())); 12632 } 12633 if (sourceItem.getTransforms() != null) { 12634 for (Transform transform : sourceItem.getTransforms()) { 12635 source.addTransform(transform); 12636 } 12637 } 12638 if (sourceColumn.getCandidateParents() != null) { 12639 for(Object item: sourceColumn.getCandidateParents()) { 12640 candidateTable candidateParent = new candidateTable(); 12641 if(item instanceof Table) { 12642 candidateParent.setId(String.valueOf(((Table)item).getId())); 12643 candidateParent.setName(getTableName((Table)item)); 12644 source.addCandidateParent(candidateParent); 12645 } 12646 else if(item instanceof ResultSet) { 12647 candidateParent.setId(String.valueOf(((ResultSet)item).getId())); 12648 candidateParent.setName(getResultSetName((ResultSet)item)); 12649 source.addCandidateParent(candidateParent); 12650 } 12651 } 12652 } 12653 append = true; 12654 relationElement.addSource(source); 12655 find = true; 12656 break; 12657 } 12658 } 12659 } 12660 } 12661 12662 if(!find) { 12663 source = new sourceColumn(); 12664 source.setId(String.valueOf(sourceColumn.getId())); 12665 source.setColumn(sourceColumn.getName()); 12666 source.setParent_id(String.valueOf(sourceColumn.getTable().getId())); 12667 source.setParent_name(sourceColumn.getTable().getName()); 12668 if (sourceItem instanceof TableColumnRelationshipElement) { 12669 source.setParent_alias( 12670 ((TableColumnRelationshipElement) sourceItem).getTableAlias()); 12671 } 12672 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 12673 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 12674 + convertCoordinate(sourceColumn.getEndPosition())); 12675 } 12676 if (sourceItem.getTransforms() != null) { 12677 for (Transform transform : sourceItem.getTransforms()) { 12678 source.addTransform(transform); 12679 } 12680 } 12681 if (sourceColumn.getCandidateParents() != null) { 12682 for(Object item: sourceColumn.getCandidateParents()) { 12683 candidateTable candidateParent = new candidateTable(); 12684 if(item instanceof Table) { 12685 candidateParent.setId(String.valueOf(((Table)item).getId())); 12686 candidateParent.setName(getTableName((Table)item)); 12687 source.addCandidateParent(candidateParent); 12688 } 12689 else if(item instanceof ResultSet) { 12690 candidateParent.setId(String.valueOf(((ResultSet)item).getId())); 12691 candidateParent.setName(getResultSetName((ResultSet)item)); 12692 source.addCandidateParent(candidateParent); 12693 } 12694 } 12695 } 12696 append = true; 12697 relationElement.addSource(source); 12698 } 12699 12700 } else { 12701 sourceColumn source = new sourceColumn(); 12702 source.setId(String.valueOf(sourceColumn.getId())); 12703 source.setColumn(sourceColumn.getName()); 12704 source.setStruct(sourceColumn.isStruct()); 12705 source.setParent_id(String.valueOf(sourceColumn.getTable().getId())); 12706 source.setParent_name(getTableName(sourceColumn.getTable())); 12707 if (sourceItem instanceof TableColumnRelationshipElement) { 12708 source.setParent_alias( 12709 ((TableColumnRelationshipElement) sourceItem).getTableAlias()); 12710 } 12711 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 12712 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 12713 + convertCoordinate(sourceColumn.getEndPosition())); 12714 } 12715 if (sourceItem.getTransforms() != null) { 12716 for (Transform transform : sourceItem.getTransforms()) { 12717 source.addTransform(transform); 12718 } 12719 } 12720 if(sourceColumn.isPseduo()) { 12721 source.setSource("system"); 12722 } 12723 if (sourceColumn.getCandidateParents() != null) { 12724 for(Object item: sourceColumn.getCandidateParents()) { 12725 candidateTable candidateParent = new candidateTable(); 12726 if(item instanceof Table) { 12727 candidateParent.setId(String.valueOf(((Table)item).getId())); 12728 candidateParent.setName(getTableName((Table)item)); 12729 source.addCandidateParent(candidateParent); 12730 } 12731 else if(item instanceof ResultSet) { 12732 candidateParent.setId(String.valueOf(((ResultSet)item).getId())); 12733 candidateParent.setName(getResultSetName((ResultSet)item)); 12734 source.addCandidateParent(candidateParent); 12735 } 12736 } 12737 } 12738 append = true; 12739 relationElement.addSource(source); 12740 } 12741 } else if (sourceElement instanceof Argument) { 12742 Argument sourceColumn = (Argument) sourceElement; 12743 sourceColumn source = new sourceColumn(); 12744 source.setId(String.valueOf(sourceColumn.getId())); 12745 source.setColumn(sourceColumn.getName()); 12746 source.setParent_id(String.valueOf(sourceColumn.getProcedure().getId())); 12747 source.setParent_name(sourceColumn.getProcedure().getName()); 12748 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 12749 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 12750 + convertCoordinate(sourceColumn.getEndPosition())); 12751 } 12752 append = true; 12753 relationElement.addSource(source); 12754 } else if (sourceElement instanceof TableRelationRows) { 12755 TableRelationRows sourceColumn = (TableRelationRows) sourceElement; 12756 sourceColumn source = new sourceColumn(); 12757 source.setId(String.valueOf(sourceColumn.getId())); 12758 source.setColumn(sourceColumn.getName()); 12759 source.setParent_id(String.valueOf(sourceColumn.getHolder().getId())); 12760 source.setParent_name(getTableName(sourceColumn.getHolder())); 12761 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 12762 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 12763 + convertCoordinate(sourceColumn.getEndPosition())); 12764 } 12765 source.setSource("system"); 12766 append = true; 12767 relationElement.addSource(source); 12768 } else if (sourceElement instanceof ResultSetRelationRows) { 12769 ResultSetRelationRows sourceColumn = (ResultSetRelationRows) sourceElement; 12770 sourceColumn source = new sourceColumn(); 12771 source.setId(String.valueOf(sourceColumn.getId())); 12772 source.setColumn(sourceColumn.getName()); 12773 source.setParent_id(String.valueOf(sourceColumn.getHolder().getId())); 12774 source.setParent_name(getResultSetName(sourceColumn.getHolder())); 12775 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 12776 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 12777 + convertCoordinate(sourceColumn.getEndPosition())); 12778 } 12779 source.setSource("system"); 12780 append = true; 12781 relationElement.addSource(source); 12782 } else if (sourceElement instanceof Constant) { 12783 Constant sourceColumn = (Constant) sourceElement; 12784 sourceColumn source = new sourceColumn(); 12785 source.setId(String.valueOf(sourceColumn.getId())); 12786 source.setColumn(sourceColumn.getName()); 12787 source.setColumn_type("constant"); 12788 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 12789 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 12790 + convertCoordinate(sourceColumn.getEndPosition())); 12791 } 12792 append = true; 12793 relationElement.addSource(source); 12794 } else if (sourceElement instanceof Table) { 12795 Table table = (Table) sourceElement; 12796 sourceColumn source = new sourceColumn(); 12797 source.setSource_id(String.valueOf(table.getId())); 12798 source.setSource_name(getTableName(table)); 12799 if (table.getStartPosition() != null && table.getEndPosition() != null) { 12800 source.setCoordinate(convertCoordinate(table.getStartPosition()) + "," 12801 + convertCoordinate(table.getEndPosition())); 12802 } 12803 append = true; 12804 relationElement.addSource(source); 12805 } 12806 12807 if (relation instanceof ImpactRelationship) { 12808 ESqlClause clause = getSqlClause(sourceItem); 12809 if (clause != null 12810 && (relationElement.getSources() != null && !relationElement.getSources().isEmpty())) { 12811 relationElement.getSources().get(relationElement.getSources().size() - 1) 12812 .setClauseType(clause.name()); 12813 } 12814 } 12815 } 12816 if (append) 12817 dataflow.getRelationships().add(relationElement); 12818 } 12819 } 12820 } 12821 12822 private boolean containsStar(Collection<RelationshipElement<?>> elements) { 12823 if (elements == null || elements.size() == 0) 12824 return false; 12825 12826 for (RelationshipElement<?> element : elements) { 12827 if (element.getElement() instanceof ResultColumn) { 12828 ResultColumn object = (ResultColumn) element.getElement(); 12829 if (object.getName().endsWith("*") && object.isShowStar()) 12830 return true; 12831 } else if (element.getElement() instanceof TableColumn) { 12832 TableColumn object = (TableColumn) element.getElement(); 12833 if (object.getName().endsWith("*") && object.isShowStar()) 12834 return true; 12835 } 12836 } 12837 return false; 12838 } 12839 12840 private Map<String, Set<String>> appendTableStarColumns = new HashMap<String, Set<String>>(); 12841 12842 // Tracks column names that have explicit (non-star) sources per target star column. 12843 // Used across relationships to prevent phantom star expansions. 12844 // Key: target star column ID, Value: set of column names with explicit sources. 12845 private Map<Long, Set<String>> explicitStarTargetColumns = new HashMap<Long, Set<String>>(); 12846 private void updateResultColumnStarLinks(dataflow dataflow, AbstractRelationship relation, int index) { 12847 try { 12848 if (option.getAnalyzeMode() == AnalyzeMode.crud) { 12849 return; 12850 } 12851 12852 ResultColumn targetColumn = (ResultColumn) relation.getTarget().getElement(); 12853 12854 Collection<RelationshipElement<?>> sourceElements = (Collection<RelationshipElement<?>>) relation.getSources(); 12855 if (sourceElements == null || sourceElements.size() == 0) 12856 return; 12857 12858 for (RelationshipElement<?> sourceItem : sourceElements) { 12859 Object sourceElement = sourceItem.getElement(); 12860 if (sourceElement instanceof ResultColumn) { 12861 ResultColumn source = (ResultColumn) sourceElement; 12862 if (source.hasStarLinkColumn()) { 12863 for (Map.Entry<String, Set<TObjectName>> item : source.getStarLinkColumns().entrySet()) { 12864 if (!targetColumn.getStarLinkColumns().containsKey(item.getKey())) { 12865 targetColumn.getStarLinkColumns().put(item.getKey(), new LinkedHashSet<TObjectName>()); 12866 } 12867 targetColumn.getStarLinkColumns().get(item.getKey()).addAll(item.getValue()); 12868 } 12869 if (!source.isShowStar()) { 12870 targetColumn.setShowStar(false); 12871 relation.setShowStarRelation(false); 12872 } 12873 } else if (!"*".equals(source.getName())) { 12874 if (source.getColumnObject() instanceof TObjectName) { 12875 if (source instanceof FunctionResultColumn) { 12876 12877 } else { 12878 targetColumn.bindStarLinkColumn((TObjectName) source.getColumnObject()); 12879 } 12880 } else if (source.getColumnObject() instanceof TResultColumn) { 12881 TResultColumn sourceColumn = (TResultColumn) source.getColumnObject(); 12882 if (sourceColumn.getAliasClause() != null) { 12883 targetColumn.bindStarLinkColumn(sourceColumn.getAliasClause().getAliasName()); 12884 } else if (sourceColumn.getFieldAttr() != null) { 12885 targetColumn.bindStarLinkColumn(sourceColumn.getFieldAttr()); 12886 } else { 12887 TObjectName column = new TObjectName(); 12888 if (sourceColumn.getExpr().getExpressionType() == EExpressionType.typecast_t) { 12889 column.setString(sourceColumn.getExpr().getLeftOperand().toString()); 12890 } else { 12891 column.setString(sourceColumn.toString()); 12892 } 12893 targetColumn.bindStarLinkColumn(column); 12894 } 12895 } 12896 } 12897 } else if (sourceElement instanceof TableColumn && !targetColumn.isStruct()) { 12898 TableColumn source = (TableColumn) sourceElement; 12899 if (!source.isPseduo() && source.hasStarLinkColumn()) { 12900 for (Map.Entry<String, Set<TObjectName>> item : source.getStarLinkColumns().entrySet()) { 12901 if (!targetColumn.getStarLinkColumns().containsKey(item.getKey())) { 12902 targetColumn.getStarLinkColumns().put(item.getKey(), 12903 new LinkedHashSet<TObjectName>()); 12904 } 12905 targetColumn.getStarLinkColumns().get(item.getKey()).addAll(item.getValue()); 12906 } 12907 if ((source.getTable().isCreateTable() || source.getTable().hasSQLEnv()) 12908 && !source.isShowStar()) { 12909 targetColumn.setShowStar(false); 12910 relation.setShowStarRelation(false); 12911 } 12912 } else if (!"*".equals(source.getName())) { 12913 targetColumn.bindStarLinkColumn(source.getColumnObject()); 12914 } 12915 } 12916 } 12917 12918 if (targetColumn.hasStarLinkColumn()) { 12919 table resultSetElement = null; 12920 for (table t : dataflow.getResultsets()) { 12921 if (t.getId().equals(String.valueOf(targetColumn.getResultSet().getId()))) { 12922 resultSetElement = t; 12923 break; 12924 } 12925 } 12926 12927 int starColumnCount = 0; 12928 for (column item : resultSetElement.getColumns()) { 12929 if (item.getName() != null && item.getName().endsWith("*")) { 12930 starColumnCount += 1; 12931 } 12932 } 12933 12934 if (resultSetElement != null && starColumnCount <= 1) { 12935 List<String> columns = targetColumn.getStarLinkColumnNames(); 12936 if (index == -1) { 12937 for (int k = 0; k < columns.size(); k++) { 12938 String columnName = columns.get(k); 12939 String id = String.valueOf(targetColumn.getId()) + "_" + k; 12940 if (appendTableStarColumns.containsKey(resultSetElement.getId()) && appendTableStarColumns.get(resultSetElement.getId()).contains(id)) { 12941 continue; 12942 } 12943 column columnElement = new column(); 12944 columnElement.setId(id); 12945 columnElement.setName(columnName); 12946 if (targetColumn.isFunction()) { 12947 columnElement.setIsFunction(String.valueOf(targetColumn.isFunction())); 12948 } 12949 if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) { 12950 columnElement.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + "," 12951 + convertCoordinate(targetColumn.getEndPosition())); 12952 } 12953 12954 if (targetColumn.getResultSet() != null && targetColumn.getResultSet().getColumns() != null) { 12955 boolean find = false; 12956 for (int i = 0; i < targetColumn.getResultSet().getColumns().size(); i++) { 12957 ResultColumn columnModel = targetColumn.getResultSet().getColumns().get(i); 12958 if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()) 12959 .equals(columnName)) { 12960 find = true; 12961 break; 12962 } 12963 } 12964 if (find) { 12965 continue; 12966 } 12967 } 12968 12969 if (!resultSetElement.getColumns().contains(columnElement)) { 12970 resultSetElement.getColumns().add(columnElement); 12971 appendTableStarColumns.putIfAbsent(resultSetElement.getId(), new HashSet<String>()); 12972 appendTableStarColumns.get(resultSetElement.getId()).add(id); 12973 } 12974 } 12975 } else { 12976 int k = index; 12977 String columnName = columns.get(k); 12978 column columnElement = new column(); 12979 columnElement.setId(String.valueOf(targetColumn.getId()) + "_" + k); 12980 columnElement.setName(columnName); 12981 if (targetColumn.isFunction()) { 12982 columnElement.setIsFunction(String.valueOf(targetColumn.isFunction())); 12983 } 12984 if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) { 12985 columnElement.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + "," 12986 + convertCoordinate(targetColumn.getEndPosition())); 12987 } 12988 12989 if (targetColumn.getResultSet() != null && targetColumn.getResultSet().getColumns() != null) { 12990 boolean find = false; 12991 for (int i = 0; i < targetColumn.getResultSet().getColumns().size(); i++) { 12992 ResultColumn columnModel = targetColumn.getResultSet().getColumns().get(i); 12993 if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equals(columnName)) { 12994 find = true; 12995 break; 12996 } 12997 } 12998 if (find) { 12999 return; 13000 } 13001 } 13002 13003 if (!resultSetElement.getColumns().contains(columnElement)) { 13004 resultSetElement.getColumns().add(columnElement); 13005 } 13006 } 13007 } 13008 } 13009 } catch (Exception e) { 13010 logger.error("updateResultColumnStarLinks occurs unknown exceptions.", e); 13011 } 13012 } 13013 13014 private void updateTableColumnStarLinks(dataflow dataflow, AbstractRelationship relation) { 13015 TableColumn targetColumn = (TableColumn) relation.getTarget().getElement(); 13016 Collection<RelationshipElement<?>> sourceElements = (Collection<RelationshipElement<?>>) relation.getSources(); 13017 if (sourceElements == null || sourceElements.size() == 0) 13018 return; 13019 13020 TableColumn sourceStarColumn = null; 13021 13022 for (RelationshipElement<?> sourceItem: sourceElements) { 13023 Object sourceElement = sourceItem.getElement(); 13024 if (sourceElement instanceof ResultColumn) { 13025 ResultColumn source = (ResultColumn) sourceElement; 13026 if(source.getResultSet() instanceof Function) { 13027 continue; 13028 } 13029 if (source.hasStarLinkColumn()) { 13030 for (Map.Entry<String, Set<TObjectName>> item : source.getStarLinkColumns().entrySet()) { 13031 if (!targetColumn.getStarLinkColumns().containsKey(item.getKey())) { 13032 targetColumn.getStarLinkColumns().put(item.getKey(), new LinkedHashSet<TObjectName>()); 13033 } 13034 targetColumn.getStarLinkColumns().get(item.getKey()).addAll(item.getValue()); 13035 } 13036 if (!source.isShowStar()) { 13037 targetColumn.setShowStar(false); 13038 relation.setShowStarRelation(false); 13039 } 13040 } else if (!"*".equals(source.getName())) { 13041 if (source.getColumnObject() instanceof TObjectName) { 13042 targetColumn.bindStarLinkColumn((TObjectName) source.getColumnObject()); 13043 } else if (source.getColumnObject() instanceof TResultColumn) { 13044 if (((TResultColumn) source.getColumnObject()).getAliasClause() != null) { 13045 TObjectName field = ((TResultColumn) source.getColumnObject()).getAliasClause() 13046 .getAliasName(); 13047 if (field != null) { 13048 targetColumn.bindStarLinkColumn(field); 13049 } 13050 } else { 13051 TObjectName field = ((TResultColumn) source.getColumnObject()).getFieldAttr(); 13052 if (field != null) { 13053 targetColumn.bindStarLinkColumn(field); 13054 } else { 13055 TObjectName column = new TObjectName(); 13056 if (((TResultColumn) source.getColumnObject()).getExpr() 13057 .getExpressionType() == EExpressionType.typecast_t) { 13058 column.setString(((TResultColumn) source.getColumnObject()).getExpr() 13059 .getLeftOperand().toString()); 13060 } else { 13061 column.setString(((TResultColumn) source.getColumnObject()).toString()); 13062 } 13063 targetColumn.bindStarLinkColumn(column); 13064 } 13065 } 13066 } 13067 } 13068 } else if (sourceElement instanceof TableColumn) { 13069 TableColumn source = (TableColumn) sourceElement; 13070 if (source.hasStarLinkColumn()) { 13071 for (Map.Entry<String, Set<TObjectName>> item : source.getStarLinkColumns().entrySet()) { 13072 if (!targetColumn.getStarLinkColumns().containsKey(item.getKey())) { 13073 targetColumn.getStarLinkColumns().put(item.getKey(), new LinkedHashSet<TObjectName>()); 13074 } 13075 targetColumn.getStarLinkColumns().get(item.getKey()).addAll(item.getValue()); 13076 } 13077 for (Map.Entry<String, Set<TObjectName>> item : targetColumn.getStarLinkColumns().entrySet()) { 13078 if (!source.getStarLinkColumns().containsKey(item.getKey())) { 13079 source.getStarLinkColumns().put(item.getKey(), new LinkedHashSet<TObjectName>()); 13080 } 13081 source.getStarLinkColumns().get(item.getKey()).addAll(item.getValue()); 13082 } 13083 13084 sourceStarColumn = source; 13085 13086 if (source.getTable().isCreateTable() && !source.isShowStar()) { 13087 targetColumn.setShowStar(false); 13088 relation.setShowStarRelation(false); 13089 } 13090 } else if (!"*".equals(source.getName())) { 13091 if (source.isStruct()) { 13092 targetColumn.bindStarLinkColumn(source.getColumnObject()); 13093 } 13094 else { 13095 TObjectName objectName = new TObjectName(); 13096 objectName.setString(DlineageUtil.getColumnNameOnly(source.getName())); 13097 targetColumn.bindStarLinkColumn(objectName); 13098 } 13099 } 13100 } 13101 } 13102 13103 if (targetColumn.hasStarLinkColumn()) { 13104 table tableElement = null; 13105 if (dataflow.getTables() != null) { 13106 for (table t : dataflow.getTables()) { 13107 if (t.getId().equals(String.valueOf(targetColumn.getTable().getId()))) { 13108 tableElement = t; 13109 break; 13110 } 13111 } 13112 } 13113 if (tableElement == null && dataflow.getViews() != null) { 13114 for (table t : dataflow.getViews()) { 13115 if (t.getId().equals(String.valueOf(targetColumn.getTable().getId()))) { 13116 tableElement = t; 13117 break; 13118 } 13119 } 13120 } 13121 if (tableElement == null && dataflow.getVariables() != null) { 13122 for (table t : dataflow.getVariables()) { 13123 if (t.getId().equals(String.valueOf(targetColumn.getTable().getId()))) { 13124 tableElement = t; 13125 break; 13126 } 13127 } 13128 } 13129 13130 if (tableElement != null) { 13131 List<String> columns = new ArrayList<String>(targetColumn.getStarLinkColumns().keySet()); 13132 for (int k = 0; k < columns.size(); k++) { 13133 String columnName = columns.get(k); 13134 if (containStarColumn(targetColumn.getTable().getColumns(), columnName)) { 13135 continue; 13136 } 13137 column columnElement = new column(); 13138 columnElement.setId(String.valueOf(targetColumn.getId()) + "_" + k); 13139 columnElement.setName(columnName); 13140 if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) { 13141 columnElement.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + "," 13142 + convertCoordinate(targetColumn.getEndPosition())); 13143 } 13144 if (!tableElement.getColumns().contains(columnElement)) { 13145 tableElement.getColumns().add(columnElement); 13146 } 13147 } 13148 } 13149 } 13150 13151 if (sourceStarColumn != null) { 13152 table tableElement = null; 13153 if (dataflow.getTables() != null) { 13154 for (table t : dataflow.getTables()) { 13155 if (t.getId().equals(String.valueOf(sourceStarColumn.getTable().getId()))) { 13156 tableElement = t; 13157 break; 13158 } 13159 } 13160 } 13161 if (tableElement == null && dataflow.getViews() != null) { 13162 for (table t : dataflow.getViews()) { 13163 if (t.getId().equals(String.valueOf(sourceStarColumn.getTable().getId()))) { 13164 tableElement = t; 13165 break; 13166 } 13167 } 13168 } 13169 if (tableElement == null && dataflow.getVariables() != null) { 13170 for (table t : dataflow.getVariables()) { 13171 if (t.getId().equals(String.valueOf(sourceStarColumn.getTable().getId()))) { 13172 tableElement = t; 13173 break; 13174 } 13175 } 13176 } 13177 13178 if (tableElement != null) { 13179 List<String> columns = new ArrayList<String>(sourceStarColumn.getStarLinkColumns().keySet()); 13180 for (int k = 0; k < columns.size(); k++) { 13181 String columnName = columns.get(k); 13182 if (containStarColumn(sourceStarColumn.getTable().getColumns(), columnName)) { 13183 continue; 13184 } 13185 column columnElement = new column(); 13186 columnElement.setId(sourceStarColumn.getId() + "_" + k); 13187 columnElement.setName(columnName); 13188 if (sourceStarColumn.getStartPosition() != null && sourceStarColumn.getEndPosition() != null) { 13189 columnElement.setCoordinate(convertCoordinate(sourceStarColumn.getStartPosition()) + "," 13190 + convertCoordinate(sourceStarColumn.getEndPosition())); 13191 } 13192 if (!tableElement.getColumns().contains(columnElement)) { 13193 tableElement.getColumns().add(columnElement); 13194 } 13195 } 13196 } 13197 } 13198 } 13199 13200 private ESqlClause getSqlClause(RelationshipElement<?> relationshipElement) { 13201 if (relationshipElement instanceof TableColumnRelationshipElement) { 13202 return ((TableColumnRelationshipElement) relationshipElement).getRelationLocation(); 13203 } else if (relationshipElement instanceof ResultColumnRelationshipElement) { 13204 return ((ResultColumnRelationshipElement) relationshipElement).getRelationLocation(); 13205 } 13206 return null; 13207 } 13208 13209 private void appendStarRelation(dataflow dataflow, AbstractRelationship relation, int index) { 13210 if(option.getAnalyzeMode() == AnalyzeMode.crud) { 13211 return; 13212 } 13213 13214 Object targetElement = relation.getTarget().getElement(); 13215 13216 relationship relationElement = new relationship(); 13217 relationElement.setType(relation.getRelationshipType().name()); 13218 if (relation.getEffectType() != null) { 13219 relationElement.setEffectType(relation.getEffectType().name()); 13220 } 13221 relationElement.setSqlHash(relation.getSqlHash()); 13222 relationElement.setSqlComment(relation.getSqlComment()); 13223 13224 if (relation.getProcedureId() != null) { 13225 relationElement.setProcedureId(String.valueOf(relation.getProcedureId())); 13226 } 13227 relationElement.setId(String.valueOf(relation.getId()) + "_" + index); 13228 if (relation.getProcess() != null) { 13229 relationElement.setProcessId(String.valueOf(relation.getProcess().getId())); 13230 if (relation.getProcess().getGspObject() != null) { 13231 relationElement.setProcessType(relation.getProcess().getGspObject().sqlstatementtype.name()); 13232 } 13233 } 13234 if (relation instanceof DataFlowRelationship) { 13235 relationElement.setSqlHash(((DataFlowRelationship) relation).getSqlHash()); 13236 relationElement.setSqlComment(((DataFlowRelationship) relation).getSqlComment()); 13237 13238 if (relation.getProcedureId() != null) { 13239 relationElement.setProcedureId(String.valueOf(relation.getProcedureId())); 13240 } 13241 } 13242 String targetName = ""; 13243 13244 if (targetElement instanceof ResultColumn) { 13245 ResultColumn targetColumn = (ResultColumn) targetElement; 13246 13247 targetName = targetColumn.getStarLinkColumnNames().get(index); 13248 13249 13250 targetColumn target = new targetColumn(); 13251 target.setId(String.valueOf(targetColumn.getId()) + "_" + index); 13252 if(targetColumn.getResultSet()!=null && targetColumn.getResultSet().getColumns()!=null) { 13253 for (int i = 0; i < targetColumn.getResultSet().getColumns().size(); i++) { 13254 ResultColumn columnModel = targetColumn.getResultSet().getColumns().get(i); 13255 if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equals(targetName)) { 13256 target.setId(String.valueOf(columnModel.getId())); 13257 break; 13258 } 13259 } 13260 } 13261 target.setColumn(targetName); 13262 target.setStruct(targetColumn.isStruct()); 13263 target.setParent_id(String.valueOf(targetColumn.getResultSet().getId())); 13264 target.setParent_name(getResultSetName(targetColumn.getResultSet())); 13265 if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) { 13266 target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + "," 13267 + convertCoordinate(targetColumn.getEndPosition())); 13268 } 13269 relationElement.setTarget(target); 13270 } else if (targetElement instanceof TableColumn) { 13271 TableColumn targetColumn = (TableColumn) targetElement; 13272 13273 targetName = targetColumn.getStarLinkColumnNames().get(index); 13274 13275 TableColumn tableColumn = searchTableColumn(targetColumn.getTable().getColumns(), targetName); 13276 13277 targetColumn target = new targetColumn(); 13278 if (tableColumn == null) { 13279 target.setId(targetColumn.getId() + "_" + index); 13280 } else { 13281 target.setId(String.valueOf(tableColumn.getId())); 13282 } 13283 target.setStruct(targetColumn.isStruct()); 13284 target.setColumn(targetName); 13285 target.setParent_id(String.valueOf(targetColumn.getTable().getId())); 13286 target.setParent_name(targetColumn.getTable().getName()); 13287 if (relation.getTarget() instanceof TableColumnRelationshipElement) { 13288 target.setParent_alias(((TableColumnRelationshipElement) relation.getTarget()).getTableAlias()); 13289 } 13290 if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) { 13291 target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + "," 13292 + convertCoordinate(targetColumn.getEndPosition())); 13293 } 13294 relationElement.setTarget(target); 13295 } else { 13296 return; 13297 } 13298 13299 Collection<RelationshipElement<?>> sourceElements = (Collection<RelationshipElement<?>>) relation.getSources(); 13300 if (sourceElements.size() == 0) { 13301 return; 13302 } 13303 13304 String targetIdentifierName = DlineageUtil.getIdentifierNormalColumnName(targetName); 13305 if (targetIdentifierName == null) { 13306 return; 13307 } 13308 13309 // Track explicit (non-star) source columns per target star column to prevent 13310 // phantom star expansions. Skip for UNION targets where branches contribute independently. 13311 long targetColumnId = -1; 13312 boolean isUnionTarget = false; 13313 if (targetElement instanceof ResultColumn) { 13314 ResultColumn tc = (ResultColumn) targetElement; 13315 targetColumnId = tc.getId(); 13316 isUnionTarget = (tc.getResultSet() instanceof SelectSetResultSet); 13317 } else if (targetElement instanceof TableColumn) { 13318 targetColumnId = ((TableColumn) targetElement).getId(); 13319 } 13320 13321 if (!isUnionTarget && targetColumnId != -1) { 13322 // Check if any source in this relationship is a non-star source matching the target 13323 // column name, AND whose parent does NOT also contribute a star source. 13324 // This distinguishes: 13325 // - "b.col_a" (definitive: b only provides explicit cols, not *) => suppress star expansion 13326 // - "aTab.id" (not definitive: aTab also provides *) => don't suppress 13327 boolean hasDefinitiveExplicitSource = hasDefinitiveNonStarSource(sourceElements, targetIdentifierName); 13328 if (hasDefinitiveExplicitSource) { 13329 if (!explicitStarTargetColumns.containsKey(targetColumnId)) { 13330 explicitStarTargetColumns.put(targetColumnId, new HashSet<String>()); 13331 } 13332 explicitStarTargetColumns.get(targetColumnId).add(targetIdentifierName); 13333 } 13334 } 13335 13336 // Column names that have explicit (non-star) sources for this target, across all relationships 13337 Set<String> targetExplicitNames = isUnionTarget ? null : explicitStarTargetColumns.get(targetColumnId); 13338 13339 for (RelationshipElement<?> sourceItem: sourceElements) { 13340 Object sourceElement = sourceItem.getElement(); 13341 if (sourceElement instanceof ResultColumn) { 13342 ResultColumn sourceColumn = (ResultColumn) sourceElement; 13343 if (sourceColumn.hasStarLinkColumn()) { 13344 List<String> linkColumnNames = sourceColumn.getStarLinkColumnNames(); 13345 int linkColumnNameSize = linkColumnNames.size(); 13346 for (int k = 0; k < linkColumnNameSize; k++) { 13347 String sourceName = linkColumnNames.get(k); 13348 if (relation.getRelationshipType() == RelationshipType.fdd) { 13349 if (!targetIdentifierName.equalsIgnoreCase(sourceName) && !"*".equals(sourceName)) 13350 continue; 13351 } 13352 // Skip star-expanded source when an explicit (non-star) source provides 13353 // the same column, either in this relationship or a prior one. 13354 if (targetExplicitNames != null && targetExplicitNames.contains(sourceName)) { 13355 continue; 13356 } 13357 sourceColumn source = new sourceColumn(); 13358 13359 boolean find = false; 13360 if(sourceColumn.getResultSet()!=null && sourceColumn.getResultSet().getColumns()!=null) { 13361 for (int i = 0; i < sourceColumn.getResultSet().getColumns().size(); i++) { 13362 ResultColumn columnModel = sourceColumn.getResultSet().getColumns().get(i); 13363 if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equals(sourceName)) { 13364 source.setId(String.valueOf(columnModel.getId())); 13365 find = true; 13366 break; 13367 } 13368 } 13369 } 13370 if(!find) { 13371 source.setId(String.valueOf(sourceColumn.getId()) + "_" + k); 13372 } 13373 source.setColumn(sourceName); 13374 source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId())); 13375 source.setParent_name(getResultSetName(sourceColumn.getResultSet())); 13376 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 13377 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 13378 + convertCoordinate(sourceColumn.getEndPosition())); 13379 } 13380 if (sourceItem.getTransforms() != null) { 13381 for (Transform transform : sourceItem.getTransforms()) { 13382 source.addTransform(transform); 13383 } 13384 } 13385 relationElement.addSource(source); 13386 } 13387 if(relationElement.getSources().isEmpty() 13388 && !(targetExplicitNames != null && targetExplicitNames.contains(targetIdentifierName)) 13389 && sourceColumn.getResultSet()!=null && sourceColumn.getResultSet().getColumns()!=null) { 13390 for (int i = 0; i < sourceColumn.getResultSet().getColumns().size(); i++) { 13391 ResultColumn columnModel = sourceColumn.getResultSet().getColumns().get(i); 13392 if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equalsIgnoreCase(targetIdentifierName)) { 13393 sourceColumn source = new sourceColumn(); 13394 source.setId(String.valueOf(columnModel.getId())); 13395 source.setColumn(columnModel.getName()); 13396 source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId())); 13397 source.setParent_name(getResultSetName(sourceColumn.getResultSet())); 13398 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 13399 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 13400 + convertCoordinate(sourceColumn.getEndPosition())); 13401 } 13402 if (sourceItem.getTransforms() != null) { 13403 for (Transform transform : sourceItem.getTransforms()) { 13404 source.addTransform(transform); 13405 } 13406 } 13407 relationElement.addSource(source); 13408 break; 13409 } 13410 } 13411 } 13412 if (relationElement.getSources().isEmpty() 13413 && !(targetExplicitNames != null && targetExplicitNames.contains(targetIdentifierName))) { 13414 TObjectName sourceStarLinkColumn = new TObjectName(); 13415 sourceStarLinkColumn.setString(targetName); 13416 boolean newBinding = sourceColumn.bindStarLinkColumn(sourceStarLinkColumn); 13417 sourceColumn source = new sourceColumn(); 13418 String sourceName = DlineageUtil.getColumnName(sourceStarLinkColumn); 13419 if (!newBinding) { 13420 source.setId(String.valueOf(sourceColumn.getId()) + "_" 13421 + sourceColumn.indexOfStarLinkColumn(sourceStarLinkColumn)); 13422 } else { 13423 source.setId(String.valueOf(sourceColumn.getId()) + "_" + linkColumnNameSize); 13424 } 13425 source.setColumn(sourceName); 13426 source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId())); 13427 source.setParent_name(getResultSetName(sourceColumn.getResultSet())); 13428 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 13429 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 13430 + convertCoordinate(sourceColumn.getEndPosition())); 13431 } 13432 if (sourceItem.getTransforms() != null) { 13433 for (Transform transform : sourceItem.getTransforms()) { 13434 source.addTransform(transform); 13435 } 13436 } 13437 relationElement.addSource(source); 13438 13439 if (newBinding) { 13440 table resultSetElement = null; 13441 for (table t : dataflow.getResultsets()) { 13442 if (t.getId().equals(String.valueOf(sourceColumn.getResultSet().getId()))) { 13443 resultSetElement = t; 13444 break; 13445 } 13446 } 13447 if (resultSetElement != null) { 13448 column columnElement = new column(); 13449 columnElement.setId(String.valueOf(sourceColumn.getId()) + "_" + linkColumnNameSize); 13450 columnElement.setName(sourceName); 13451 if (sourceColumn.isFunction()) { 13452 columnElement.setIsFunction(String.valueOf(sourceColumn.isFunction())); 13453 } 13454 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 13455 columnElement.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 13456 + convertCoordinate(sourceColumn.getEndPosition())); 13457 } 13458 resultSetElement.getColumns().add(columnElement); 13459 } 13460 } 13461 } 13462 } else { 13463 sourceColumn source = new sourceColumn(); 13464 source.setId(String.valueOf(sourceColumn.getId())); 13465 source.setColumn(sourceColumn.getName()); 13466 source.setStruct(sourceColumn.isStruct()); 13467 source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId())); 13468 source.setParent_name(getResultSetName(sourceColumn.getResultSet())); 13469 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 13470 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 13471 + convertCoordinate(sourceColumn.getEndPosition())); 13472 } 13473 if (relation.getRelationshipType() == RelationshipType.fdd) { 13474 if (!targetIdentifierName 13475 .equalsIgnoreCase(DlineageUtil.getIdentifierNormalColumnName(sourceColumn.getName()))) { 13476 if (!"*".equals(sourceColumn.getName())) { 13477 continue; 13478 } 13479 else { 13480 boolean flag = false; 13481 for(ResultColumn column: sourceColumn.getResultSet().getColumns()) { 13482 if(targetIdentifierName 13483 .equalsIgnoreCase(DlineageUtil.getIdentifierNormalColumnName(column.getName()))) { 13484 flag = true; 13485 break; 13486 } 13487 } 13488 if(flag) { 13489 continue; 13490 } 13491 } 13492 } 13493 } 13494 if (sourceItem.getTransforms() != null) { 13495 for (Transform transform : sourceItem.getTransforms()) { 13496 source.addTransform(transform); 13497 } 13498 } 13499 relationElement.addSource(source); 13500 } 13501 } else if (sourceElement instanceof TableColumn) { 13502 TableColumn sourceColumn = (TableColumn) sourceElement; 13503 if (!sourceColumn.isPseduo() && sourceColumn.hasStarLinkColumn()) { 13504 List<String> linkColumnNames = sourceColumn.getStarLinkColumnNames(); 13505 int linkColumnNameSize = linkColumnNames.size(); 13506 for (int k = 0; k < linkColumnNameSize; k++) { 13507 String sourceName = linkColumnNames.get(k); 13508 if (relation.getRelationshipType() == RelationshipType.fdd) { 13509 if (!targetIdentifierName.equalsIgnoreCase(sourceName) && !"*".equals(sourceName)) 13510 continue; 13511 } 13512 13513 TableColumn tableColumn = searchTableColumn(sourceColumn.getTable().getColumns(), sourceName); 13514 13515 sourceColumn source = new sourceColumn(); 13516 if (tableColumn == null) { 13517 source.setId(sourceColumn.getId() + "_" + k); 13518 } else { 13519 source.setId(String.valueOf(tableColumn.getId())); 13520 } 13521 source.setColumn(sourceName); 13522 source.setStruct(sourceColumn.isStruct()); 13523 if (containStarColumn(sourceElements, sourceName)) { 13524 continue; 13525 } 13526 // Cross-relationship check: skip if explicit source was found in prior relationship 13527 if (targetExplicitNames != null && targetExplicitNames.contains(sourceName)) { 13528 continue; 13529 } 13530 if (sourceColumn.getTable().getColumns().size() > 1) { 13531 for (int y = 0; y < sourceColumn.getTable().getColumns().size(); y++) { 13532 if (sourceColumn.getTable().getColumns().get(y).getName() 13533 .equalsIgnoreCase(sourceName)) { 13534 source.setId(String.valueOf(sourceColumn.getTable().getColumns().get(y).getId())); 13535 break; 13536 } 13537 } 13538 } 13539 source.setParent_id(String.valueOf(sourceColumn.getTable().getId())); 13540 source.setParent_name(getTableName(sourceColumn.getTable())); 13541 if (sourceItem instanceof TableColumnRelationshipElement) { 13542 source.setParent_alias( 13543 ((TableColumnRelationshipElement) sourceItem).getTableAlias()); 13544 } 13545 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 13546 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 13547 + convertCoordinate(sourceColumn.getEndPosition())); 13548 } 13549 if (sourceItem.getTransforms() != null) { 13550 for (Transform transform : sourceItem.getTransforms()) { 13551 source.addTransform(transform); 13552 } 13553 } 13554 relationElement.addSource(source); 13555 } 13556 } else { 13557 sourceColumn source = new sourceColumn(); 13558 source.setId(String.valueOf(sourceColumn.getId())); 13559 source.setColumn(sourceColumn.getName()); 13560 source.setStruct(sourceColumn.isStruct()); 13561 source.setParent_id(String.valueOf(sourceColumn.getTable().getId())); 13562 source.setParent_name(getTableName(sourceColumn.getTable())); 13563 if (sourceItem instanceof TableColumnRelationshipElement) { 13564 source.setParent_alias(((TableColumnRelationshipElement) sourceItem).getTableAlias()); 13565 } 13566 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 13567 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 13568 + convertCoordinate(sourceColumn.getEndPosition())); 13569 } 13570 if (relation.getRelationshipType() == RelationshipType.fdd) { 13571 if (!targetIdentifierName 13572 .equalsIgnoreCase(DlineageUtil.getIdentifierNormalColumnName(sourceColumn.getName())) 13573 && !"*".equals(sourceColumn.getName())) 13574 continue; 13575 } 13576 if (sourceItem.getTransforms() != null) { 13577 for (Transform transform : sourceItem.getTransforms()) { 13578 source.addTransform(transform); 13579 } 13580 } 13581 relationElement.addSource(source); 13582 } 13583 } 13584 } 13585 13586 if (relationElement.getTarget() != null && relationElement.getSources() != null 13587 && !relationElement.getSources().isEmpty()) { 13588 dataflow.getRelationships().add(relationElement); 13589 } 13590 } 13591 13592 private String getColumnName(TObjectName column) { 13593 if (column == null) { 13594 return null; 13595 } 13596 String name = column.getColumnNameOnly(); 13597 if (name == null || "".equals(name.trim())) { 13598 return DlineageUtil.getIdentifierNormalColumnName(column.toString().trim()); 13599 } else 13600 return DlineageUtil.getIdentifierNormalColumnName(name.trim()); 13601 } 13602 13603 /** 13604 * For BigQuery/Redshift struct field access, returns the full struct path 13605 * (e.g., "customer.name" from ColumnSource with exposedName="customer", fieldPath=["name"]). 13606 * Checks StructFieldHint first (for 3+ part no-alias), then ColumnSource (for 2-part/alias). 13607 * Returns null if this is not a struct field access. 13608 */ 13609 private String getStructFieldFullName(TObjectName column) { 13610 if (column == null) return null; 13611 if (getOption().getVendor() != EDbVendor.dbvbigquery 13612 && getOption().getVendor() != EDbVendor.dbvredshift) return null; 13613 // Priority 1: StructFieldHint (side-channel, for 3+ part no-alias deep struct access) 13614 gudusoft.gsqlparser.resolver2.model.StructFieldHint hint = column.getStructFieldHint(); 13615 if (hint != null && hint.getFieldPath() != null && !hint.getFieldPath().isEmpty()) { 13616 return hint.toFullReference(); 13617 } 13618 // Priority 2: ColumnSource (main resolution, for 2-part and alias cases) 13619 gudusoft.gsqlparser.resolver2.model.ColumnSource source = column.getColumnSource(); 13620 if (source != null && source.isStructFieldAccess() && source.hasFieldPath()) { 13621 return source.getFieldPath().toFullReference(source.getExposedName()); 13622 } 13623 return null; 13624 } 13625 13626 /** 13627 * Get the base column name for a struct field access column. 13628 * Checks StructFieldHint first (3+ part no-alias), then ColumnSource (2-part/alias). 13629 * Returns null if not a struct field access. 13630 */ 13631 private String getStructFieldBaseName(TObjectName column) { 13632 if (column == null) return null; 13633 gudusoft.gsqlparser.resolver2.model.StructFieldHint hint = column.getStructFieldHint(); 13634 if (hint != null && hint.getBaseColumn() != null) { 13635 return hint.getBaseColumn(); 13636 } 13637 gudusoft.gsqlparser.resolver2.model.ColumnSource source = column.getColumnSource(); 13638 if (source != null && source.isStructFieldAccess()) { 13639 return source.getExposedName(); 13640 } 13641 return null; 13642 } 13643 13644 private String getColumnName(String column) { 13645 if (column == null) { 13646 return null; 13647 } 13648 String name = column.substring(column.lastIndexOf(".") + 1); 13649 if (name == null || "".equals(name.trim())) { 13650 return DlineageUtil.getIdentifierNormalColumnName(column.toString().trim()); 13651 } else 13652 return DlineageUtil.getIdentifierNormalColumnName(name.trim()); 13653 } 13654 13655 private String getColumnNameOnly(String column) { 13656 if (column == null) { 13657 return null; 13658 } 13659 return DlineageUtil.getColumnNameOnly(column); 13660 } 13661 13662 private void appendRecordSetRelation(dataflow dataflow, Relationship[] relations) { 13663 for (int i = 0; i < relations.length; i++) { 13664 AbstractRelationship relation = (AbstractRelationship) relations[i]; 13665 relationship relationElement = new relationship(); 13666 relationElement.setType(relation.getRelationshipType().name()); 13667 if (relation.getFunction() != null) { 13668 relationElement.setFunction(relation.getFunction()); 13669 } 13670 if (relation.getEffectType() != null) { 13671 relationElement.setEffectType(relation.getEffectType().name()); 13672 } 13673 relationElement.setSqlHash(relation.getSqlHash()); 13674 relationElement.setSqlComment(relation.getSqlComment()); 13675 13676 if (relation.getProcedureId() != null) { 13677 relationElement.setProcedureId(String.valueOf(relation.getProcedureId())); 13678 } 13679 relationElement.setId(String.valueOf(relation.getId())); 13680 13681 if (relation instanceof RecordSetRelationship) { 13682 RecordSetRelationship recordCountRelation = (RecordSetRelationship) relation; 13683 13684 Object targetElement = recordCountRelation.getTarget().getElement(); 13685 if (targetElement instanceof ResultColumn) { 13686 ResultColumn targetColumn = (ResultColumn) targetElement; 13687 targetColumn target = new targetColumn(); 13688 target.setId(String.valueOf(targetColumn.getId())); 13689 target.setColumn(targetColumn.getName()); 13690 target.setStruct(targetColumn.isStruct()); 13691 target.setFunction(recordCountRelation.getAggregateFunction()); 13692 target.setParent_id(String.valueOf(targetColumn.getResultSet().getId())); 13693 target.setParent_name(getResultSetName(targetColumn.getResultSet())); 13694 if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) { 13695 target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + "," 13696 + convertCoordinate(targetColumn.getEndPosition())); 13697 } 13698 relationElement.setTarget(target); 13699 } else if (targetElement instanceof TableColumn) { 13700 TableColumn targetColumn = (TableColumn) targetElement; 13701 targetColumn target = new targetColumn(); 13702 target.setId(String.valueOf(targetColumn.getId())); 13703 target.setColumn(targetColumn.getName()); 13704 target.setStruct(targetColumn.isStruct()); 13705 target.setFunction(recordCountRelation.getAggregateFunction()); 13706 target.setParent_id(String.valueOf(targetColumn.getTable().getId())); 13707 target.setParent_name(getTableName(targetColumn.getTable())); 13708 if (recordCountRelation.getTarget() instanceof TableColumnRelationshipElement) { 13709 target.setParent_alias( 13710 ((TableColumnRelationshipElement) recordCountRelation.getTarget()).getTableAlias()); 13711 } 13712 if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) { 13713 target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + "," 13714 + convertCoordinate(targetColumn.getEndPosition())); 13715 } 13716 relationElement.setTarget(target); 13717 } else if (targetElement instanceof ResultSetRelationRows) { 13718 ResultSetRelationRows targetColumn = (ResultSetRelationRows) targetElement; 13719 targetColumn target = new targetColumn(); 13720 target.setId(String.valueOf(targetColumn.getId())); 13721 target.setColumn(targetColumn.getName()); 13722 target.setParent_id(String.valueOf(targetColumn.getHolder().getId())); 13723 target.setParent_name(getResultSetName(targetColumn.getHolder())); 13724 if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) { 13725 target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + "," 13726 + convertCoordinate(targetColumn.getEndPosition())); 13727 } 13728 target.setSource("system"); 13729 relationElement.setTarget(target); 13730 } else { 13731 continue; 13732 } 13733 13734 Collection<RelationshipElement<?>> sourceElements = (Collection<RelationshipElement<?>>)recordCountRelation.getSources(); 13735 if (sourceElements.size() == 0) { 13736 continue; 13737 } 13738 13739 boolean append = false; 13740 for (RelationshipElement<?> sourceItem: sourceElements) { 13741 Object sourceElement = sourceItem.getElement(); 13742 if (sourceElement instanceof Table) { 13743 Table table = (Table) sourceElement; 13744 sourceColumn source = new sourceColumn(); 13745 source.setSource_id(String.valueOf(table.getId())); 13746 source.setSource_name(getTableName(table)); 13747 if (table.getStartPosition() != null && table.getEndPosition() != null) { 13748 source.setCoordinate(convertCoordinate(table.getStartPosition()) + "," 13749 + convertCoordinate(table.getEndPosition())); 13750 } 13751 append = true; 13752 relationElement.addSource(source); 13753 } else if (sourceElement instanceof QueryTable) { 13754 QueryTable table = (QueryTable) sourceElement; 13755 sourceColumn source = new sourceColumn(); 13756 source.setSource_id(String.valueOf(table.getId())); 13757 source.setSource_name(getResultSetName(table)); 13758 if (table.getStartPosition() != null && table.getEndPosition() != null) { 13759 source.setCoordinate(convertCoordinate(table.getStartPosition()) + "," 13760 + convertCoordinate(table.getEndPosition())); 13761 } 13762 append = true; 13763 relationElement.addSource(source); 13764 } else if (sourceElement instanceof TableRelationRows) { 13765 TableRelationRows relationRows = (TableRelationRows) sourceElement; 13766 sourceColumn source = new sourceColumn(); 13767 source.setId(String.valueOf(relationRows.getId())); 13768 source.setColumn(relationRows.getName()); 13769 source.setParent_id(String.valueOf(relationRows.getHolder().getId())); 13770 source.setParent_name(getTableName(relationRows.getHolder())); 13771 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 13772 source.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 13773 + convertCoordinate(relationRows.getEndPosition())); 13774 } 13775 source.setSource("system"); 13776 append = true; 13777 relationElement.addSource(source); 13778 } else if (sourceElement instanceof ResultSetRelationRows) { 13779 ResultSetRelationRows relationRows = (ResultSetRelationRows) sourceElement; 13780 sourceColumn source = new sourceColumn(); 13781 source.setId(String.valueOf(relationRows.getId())); 13782 source.setColumn(relationRows.getName()); 13783 source.setParent_id(String.valueOf(relationRows.getHolder().getId())); 13784 source.setParent_name(getResultSetName(relationRows.getHolder())); 13785 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 13786 source.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 13787 + convertCoordinate(relationRows.getEndPosition())); 13788 } 13789 source.setSource("system"); 13790 append = true; 13791 relationElement.addSource(source); 13792 } else if (sourceElement instanceof TableColumn) { 13793 TableColumn sourceColumn = (TableColumn) sourceElement; 13794 sourceColumn source = new sourceColumn(); 13795 source.setId(String.valueOf(sourceColumn.getId())); 13796 source.setColumn(sourceColumn.getName()); 13797 source.setStruct(sourceColumn.isStruct()); 13798 source.setParent_id(String.valueOf(sourceColumn.getTable().getId())); 13799 source.setParent_name(getTableName(sourceColumn.getTable())); 13800 if (sourceItem instanceof TableColumnRelationshipElement) { 13801 source.setParent_alias( 13802 ((TableColumnRelationshipElement) sourceItem).getTableAlias()); 13803 } 13804 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 13805 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 13806 + convertCoordinate(sourceColumn.getEndPosition())); 13807 } 13808 append = true; 13809 relationElement.addSource(source); 13810 } 13811 if (sourceElement instanceof ResultColumn) { 13812 ResultColumn sourceColumn = (ResultColumn) sourceElement; 13813 sourceColumn source = new sourceColumn(); 13814 source.setId(String.valueOf(sourceColumn.getId())); 13815 source.setColumn(sourceColumn.getName()); 13816 source.setStruct(sourceColumn.isStruct()); 13817 source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId())); 13818 source.setParent_name(getResultSetName(sourceColumn.getResultSet())); 13819 if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) { 13820 source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + "," 13821 + convertCoordinate(sourceColumn.getEndPosition())); 13822 } 13823 append = true; 13824 relationElement.addSource(source); 13825 } 13826 } 13827 13828 if (append) 13829 dataflow.getRelationships().add(relationElement); 13830 } 13831 } 13832 } 13833 13834 private void appendCallRelation(dataflow dataflow, Relationship[] relations) { 13835 for (int i = 0; i < relations.length; i++) { 13836 AbstractRelationship relation = (AbstractRelationship) relations[i]; 13837 relationship relationElement = new relationship(); 13838 relationElement.setType(relation.getRelationshipType().name()); 13839 if (relation.getFunction() != null) { 13840 relationElement.setFunction(relation.getFunction()); 13841 } 13842 if (relation.getEffectType() != null) { 13843 relationElement.setEffectType(relation.getEffectType().name()); 13844 } 13845 relationElement.setSqlHash(relation.getSqlHash()); 13846 relationElement.setSqlComment(relation.getSqlComment()); 13847 13848 if (relation.getProcedureId() != null) { 13849 relationElement.setProcedureId(String.valueOf(relation.getProcedureId())); 13850 } 13851 relationElement.setId(String.valueOf(relation.getId())); 13852 13853 if (relation instanceof CallRelationship) { 13854 CallRelationship callRelation = (CallRelationship) relation; 13855 13856 if (callRelation.getCallObject() != null) { 13857 relationElement.setCallStmt(callRelation.getCallObject().toString()); 13858 if (callRelation.getStartPosition() != null && callRelation.getEndPosition() != null) { 13859 relationElement.setCallCoordinate(convertCoordinate(callRelation.getStartPosition()) + "," 13860 + convertCoordinate(callRelation.getEndPosition())); 13861 } 13862 } 13863 13864 if (Boolean.TRUE.equals(callRelation.getBuiltIn())) { 13865 relationElement.setBuiltIn(true); 13866 } 13867 Object targetElement = callRelation.getTarget().getElement(); 13868 if (targetElement instanceof Procedure) { 13869 Procedure procedure = (Procedure) targetElement; 13870 targetColumn target = new targetColumn(); 13871 target.setId(String.valueOf(procedure.getId())); 13872 target.setName(getProcedureName(procedure)); 13873 if (procedure.getStartPosition() != null && procedure.getEndPosition() != null) { 13874 target.setCoordinate(convertCoordinate(procedure.getStartPosition()) + "," 13875 + convertCoordinate(procedure.getEndPosition())); 13876 } 13877 String clazz = procedure.getProcedureObject().getClass().getSimpleName().toLowerCase(); 13878 if (clazz.indexOf("function") != -1) { 13879 target.setType("function"); 13880 } else if (clazz.indexOf("trigger") != -1) { 13881 target.setType("trigger"); 13882 } else if (clazz.indexOf("macro") != -1) { 13883 target.setType("macro"); 13884 } else { 13885 target.setType("procedure"); 13886 } 13887 relationElement.setCaller(target); 13888 } else { 13889 continue; 13890 } 13891 13892 Collection<RelationshipElement<?>> sourceElements = (Collection<RelationshipElement<?>>)callRelation.getSources(); 13893 if (sourceElements.size() == 0) { 13894 continue; 13895 } 13896 13897 boolean append = false; 13898 for (RelationshipElement<?> sourceItem: sourceElements) { 13899 Object sourceElement = sourceItem.getElement(); 13900 if (sourceElement instanceof Procedure) { 13901 Procedure procedure = (Procedure) sourceElement; 13902 sourceColumn source = new sourceColumn(); 13903 source.setId(String.valueOf(procedure.getId())); 13904 source.setName(getProcedureName(procedure)); 13905 if (procedure.getStartPosition() != null && procedure.getEndPosition() != null) { 13906 source.setCoordinate(convertCoordinate(procedure.getStartPosition()) + "," 13907 + convertCoordinate(procedure.getEndPosition())); 13908 } 13909 String clazz = procedure.getProcedureObject().getClass().getSimpleName().toLowerCase(); 13910 if (clazz.indexOf("function") != -1) { 13911 source.setType("function"); 13912 } else if (clazz.indexOf("trigger") != -1) { 13913 source.setType("trigger"); 13914 } else if (clazz.indexOf("macro") != -1) { 13915 source.setType("macro"); 13916 } else { 13917 source.setType("procedure"); 13918 } 13919 append = true; 13920 relationElement.getCallees().add(source); 13921 } else if (sourceElement instanceof Function) { 13922 Function function = (Function) sourceElement; 13923 sourceColumn source = new sourceColumn(); 13924 source.setId(String.valueOf(function.getId())); 13925 source.setName(getFunctionName(function.getFunctionObject())); 13926 if (function.getStartPosition() != null && function.getEndPosition() != null) { 13927 source.setCoordinate(convertCoordinate(function.getStartPosition()) + "," 13928 + convertCoordinate(function.getEndPosition())); 13929 } 13930 source.setType("function"); 13931 append = true; 13932 relationElement.getCallees().add(source); 13933 } 13934 } 13935 13936 if (append) 13937 dataflow.getRelationships().add(relationElement); 13938 } 13939 } 13940 } 13941 13942 private void appendResultSets(dataflow dataflow) { 13943 Set<ResultSet> resultSets = modelManager.getResultSets(); 13944 for (ResultSet resultSet: resultSets) { 13945 appendResultSet(dataflow, resultSet); 13946 } 13947 } 13948 13949 private void appendResultSet(dataflow dataflow, ResultSet resultSetModel) { 13950 if (!appendResultSets.contains(resultSetModel)) { 13951 appendResultSets.add(resultSetModel); 13952 } else { 13953 return; 13954 } 13955 13956 table resultSetElement = new table(); 13957 resultSetElement.setId(String.valueOf(resultSetModel.getId())); 13958 resultSetElement.setServer(resultSetModel.getServer()); 13959 if (!SQLUtil.isEmpty(resultSetModel.getDatabase())) { 13960 resultSetElement.setDatabase(resultSetModel.getDatabase()); 13961 } 13962 if (!SQLUtil.isEmpty(resultSetModel.getSchema())) { 13963 resultSetElement.setSchema(resultSetModel.getSchema()); 13964 } 13965 resultSetElement.setName(getResultSetName(resultSetModel)); 13966 resultSetElement.setType(getResultSetType(resultSetModel)); 13967 // if ((ignoreRecordSet || simpleOutput) && resultSetModel.isTarget()) { 13968 resultSetElement.setIsTarget(String.valueOf(resultSetModel.isTarget())); 13969 // } 13970 resultSetElement.setIsDetermined(String.valueOf(resultSetModel.isDetermined())); 13971 if (resultSetModel.getStartPosition() != null && resultSetModel.getEndPosition() != null) { 13972 resultSetElement.setCoordinate(convertCoordinate(resultSetModel.getStartPosition()) + "," 13973 + convertCoordinate(resultSetModel.getEndPosition())); 13974 } 13975 dataflow.getResultsets().add(resultSetElement); 13976 13977 List<ResultColumn> columns = resultSetModel.getColumns(); 13978 13979 Map<String, Integer> columnCounts = new HashMap<String, Integer>(); 13980 for (ResultColumn column : columns) { 13981 String columnName = DlineageUtil.getIdentifierNormalColumnName(column.getName()); 13982 if (!columnCounts.containsKey(columnName)) { 13983 columnCounts.put(columnName, 0); 13984 } 13985 columnCounts.put(columnName, columnCounts.get(columnName) + 1); 13986 // if (column.hasStarLinkColumn()) { 13987 // List<String> starLinkColumns = column.getStarLinkColumnNames(); 13988 // for (int k = 0; k < starLinkColumns.size(); k++) { 13989 // columnName = starLinkColumns.get(k); 13990 // if (!columnCounts.containsKey(columnName)) { 13991 // columnCounts.put(columnName, 0); 13992 // } 13993 // columnCounts.put(columnName, columnCounts.get(columnName) + 1); 13994 // } 13995 // } 13996 } 13997 13998 for (int j = 0; j < columns.size(); j++) { 13999 ResultColumn columnModel = columns.get(j); 14000 if (columnModel.hasStarLinkColumn()) { 14001 // List<String> starLinkColumns = 14002 // columnModel.getStarLinkColumnNames(); 14003 // for (int k = 0; k < starLinkColumns.size(); k++) { 14004 // column columnElement = new column(); 14005 // columnElement.setId( String.valueOf(columnModel.getId()) + 14006 // "_" + k); 14007 // String columnName = starLinkColumns.get(k); 14008 // columnElement.setName(columnName); 14009 // if(columnModel.isFunction()){ 14010 // columnElement.setIsFunction(String.valueOf(columnModel.isFunction())); 14011 // } 14012 // if (columnModel.getStartPosition() != null && 14013 // columnModel.getEndPosition() != null) { 14014 // columnElement.setCoordinate( 14015 // columnModel.getStartPosition() + "," + 14016 // columnModel.getEndPosition()); 14017 // } 14018 // String identifier = columnName; 14019 // if(columnCounts.containsKey(identifier) && 14020 // columnCounts.get(identifier)>1){ 14021 // TObjectName column = 14022 // columnModel.getStarLinkColumns().get(columnName).iterator().next(); 14023 // if(!SQLUtil.isEmpty(getQualifiedTable(column))){ 14024 // columnElement.setQualifiedTable(getQualifiedTable(column)); 14025 // } 14026 // } 14027 // resultSetElement.getColumns().add(columnElement); 14028 // } 14029 if (columnModel.isShowStar()) { 14030 column columnElement = new column(); 14031 columnElement.setId(String.valueOf(columnModel.getId())); 14032 columnElement.setName(columnModel.getName()); 14033 if (columnModel.isFunction()) { 14034 columnElement.setIsFunction(String.valueOf(columnModel.isFunction())); 14035 } 14036 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 14037 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 14038 + convertCoordinate(columnModel.getEndPosition())); 14039 } 14040 14041 String identifier = DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()); 14042 if (columnCounts.containsKey(identifier) && columnCounts.get(identifier) > 1) { 14043 String qualifiedTable = getQualifiedTable(columnModel); 14044 if (!SQLUtil.isEmpty(qualifiedTable)) { 14045 columnElement.setQualifiedTable(qualifiedTable); 14046 } 14047 } 14048 resultSetElement.getColumns().add(columnElement); 14049 } 14050 } else { 14051 column columnElement = new column(); 14052 columnElement.setId(String.valueOf(columnModel.getId())); 14053 columnElement.setName(columnModel.getName()); 14054 if (columnModel.isFunction()) { 14055 columnElement.setIsFunction(String.valueOf(columnModel.isFunction())); 14056 } 14057 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 14058 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 14059 + convertCoordinate(columnModel.getEndPosition())); 14060 } 14061 14062 String identifier = DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()); 14063 if (columnCounts.containsKey(identifier) && columnCounts.get(identifier) > 1) { 14064 String qualifiedTable = getQualifiedTable(columnModel); 14065 if (!SQLUtil.isEmpty(qualifiedTable)) { 14066 columnElement.setQualifiedTable(qualifiedTable); 14067 } 14068 } 14069 resultSetElement.getColumns().add(columnElement); 14070 } 14071 } 14072 14073 ResultSetRelationRows relationRows = resultSetModel.getRelationRows(); 14074 if (relationRows.hasRelation()) { 14075 column relationRowsElement = new column(); 14076 relationRowsElement.setId(String.valueOf(relationRows.getId())); 14077 relationRowsElement.setName(relationRows.getName()); 14078 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 14079 relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 14080 + convertCoordinate(relationRows.getEndPosition())); 14081 } 14082 relationRowsElement.setSource("system"); 14083 resultSetElement.getColumns().add(relationRowsElement); 14084 } 14085 } 14086 14087 private String getQualifiedTable(ResultColumn columnModel) { 14088 if (columnModel.getColumnObject() instanceof TObjectName) { 14089 return getQualifiedTable((TObjectName) columnModel.getColumnObject()); 14090 } 14091 if (columnModel.getColumnObject() instanceof TResultColumn) { 14092 TObjectName field = ((TResultColumn) columnModel.getColumnObject()).getFieldAttr(); 14093 if (field != null) { 14094 return getQualifiedTable(field); 14095 } 14096 } 14097 return null; 14098 } 14099 14100 private String getQualifiedTable(TObjectName column) { 14101 if (column == null) 14102 return null; 14103 String[] splits = column.toString().split("\\."); 14104 if (splits.length > 1) { 14105 return splits[splits.length - 2]; 14106 } 14107 return null; 14108 } 14109 14110 /** 14111 * Get the qualified prefix (schema.table) from a column name for 3-part names. 14112 * For example, for "sch.pk_constv2.c_cdsl", returns "sch.pk_constv2". 14113 * Returns null if the column doesn't have both schema and table parts. 14114 */ 14115 private String getQualifiedPrefixFromColumn(TObjectName column) { 14116 if (column == null) return null; 14117 14118 // Check if both schema and table tokens are present (3-part name) 14119 String schemaStr = column.getSchemaString(); 14120 String tableStr = column.getTableString(); 14121 14122 if (schemaStr != null && !schemaStr.isEmpty() && 14123 tableStr != null && !tableStr.isEmpty()) { 14124 return schemaStr + "." + tableStr; 14125 } 14126 14127 // Fallback: parse from toString() for complex cases 14128 String[] splits = column.toString().split("\\."); 14129 if (splits.length >= 3) { 14130 // Return all parts except the last one (column name) 14131 StringBuilder prefix = new StringBuilder(); 14132 for (int i = 0; i < splits.length - 1; i++) { 14133 if (i > 0) prefix.append("."); 14134 prefix.append(splits[i]); 14135 } 14136 return prefix.toString(); 14137 } 14138 14139 return null; 14140 } 14141 14142 private String getResultSetType(ResultSet resultSetModel) { 14143 if (resultSetModel instanceof QueryTable) { 14144 QueryTable table = (QueryTable) resultSetModel; 14145 if (table.getTableObject().getCTE() != null) { 14146 return "with_cte"; 14147 } 14148 } 14149 14150 if (resultSetModel instanceof SelectSetResultSet) { 14151 ESetOperatorType type = ((SelectSetResultSet) resultSetModel).getSetOperatorType(); 14152 return "select_" + type.name(); 14153 } 14154 14155 if (resultSetModel instanceof SelectResultSet) { 14156 if (((SelectResultSet) resultSetModel).getSelectStmt().getParentStmt() instanceof TInsertSqlStatement) { 14157 return "insert-select"; 14158 } 14159 if (((SelectResultSet) resultSetModel).getSelectStmt().getParentStmt() instanceof TUpdateSqlStatement) { 14160 return "update-select"; 14161 } 14162 } 14163 14164 if (resultSetModel.getGspObject() instanceof TMergeUpdateClause) { 14165 return "merge-update"; 14166 } 14167 14168 if (resultSetModel.getGspObject() instanceof TOutputClause) { 14169 return ResultSetType.output.name(); 14170 } 14171 14172 if (resultSetModel.getGspObject() instanceof TMergeInsertClause) { 14173 return "merge-insert"; 14174 } 14175 14176 if (resultSetModel.getGspObject() instanceof TUpdateSqlStatement) { 14177 return "update-set"; 14178 } 14179 14180 if (resultSetModel.getGspObject() instanceof TFunctionCall && ((TFunctionCall)resultSetModel.getGspObject()).getFunctionType() == EFunctionType.array_t) { 14181 return ResultSetType.array.name(); 14182 } 14183 14184 if (resultSetModel.getGspObject() instanceof TFunctionCall && ((TFunctionCall)resultSetModel.getGspObject()).getFunctionType() == EFunctionType.struct_t) { 14185 return ResultSetType.struct.name(); 14186 } 14187 14188 if (resultSetModel.getGspObject() instanceof TFunctionCall || resultSetModel instanceof Function) { 14189 return ResultSetType.function.name(); 14190 } 14191 14192 if (resultSetModel.getGspObject() instanceof TAliasClause) { 14193 return ResultSetType.alias.name(); 14194 } 14195 14196 if (resultSetModel.getGspObject() instanceof TCursorDeclStmt) { 14197 return ResultSetType.cursor.name(); 14198 } 14199 14200 if (resultSetModel instanceof PivotedTable) { 14201 if (((PivotedTable) resultSetModel).isUnpivoted()) { 14202 return ResultSetType.unpivot_table.name(); 14203 } 14204 return ResultSetType.pivot_table.name(); 14205 } 14206 14207 return "select_list"; 14208 } 14209 14210 private String getTableName(Table tableModel) { 14211 if (modelManager.DISPLAY_NAME.containsKey(tableModel.getId())) { 14212 return modelManager.DISPLAY_NAME.get(tableModel.getId()); 14213 } 14214 14215 String tableName; 14216 if (tableModel.getFullName() != null && tableModel.getFullName().trim().length() > 0) { 14217 return tableModel.getFullName(); 14218 } 14219 if (tableModel.getAlias() != null && tableModel.getAlias().trim().length() > 0) { 14220 tableName = getResultSetWithId("RESULT_OF_" + tableModel.getAlias()); 14221 14222 } else { 14223 tableName = getResultSetDisplayId("RS"); 14224 } 14225 modelManager.DISPLAY_NAME.put(tableModel.getId(), tableName); 14226 return tableName; 14227 } 14228 14229 private String getProcedureName(Procedure procedureModel) { 14230 if (modelManager.DISPLAY_NAME.containsKey(procedureModel.getId())) { 14231 return modelManager.DISPLAY_NAME.get(procedureModel.getId()); 14232 } 14233 14234 String procedureName = procedureModel.getFullName(); 14235 14236 modelManager.DISPLAY_NAME.put(procedureModel.getId(), procedureName); 14237 return procedureName; 14238 } 14239 14240 private String getProcessName(Process processModel) { 14241 if (modelManager.DISPLAY_NAME.containsKey(processModel.getId())) { 14242 return modelManager.DISPLAY_NAME.get(processModel.getId()); 14243 } else { 14244 if (processModel.getCustomType() != null) { 14245 String name = processModel.getCustomType(); 14246 modelManager.DISPLAY_NAME.put(processModel.getId(), name); 14247 return name; 14248 } 14249 String name = processModel.getType(); 14250 String procedureName = getProcedureParentName(processModel.getGspObject()); 14251 if (procedureName != null) { 14252 name = getResultSetDisplayId(procedureName + " " + name); 14253 } else { 14254 name = getResultSetDisplayId("Query " + name); 14255 } 14256 modelManager.DISPLAY_NAME.put(processModel.getId(), name); 14257 return name; 14258 } 14259 } 14260 14261 private String getDisplayIdByType(String type) { 14262 if (!modelManager.DISPLAY_ID.containsKey(type)) { 14263 modelManager.DISPLAY_ID.put(type, option.getStartId() + 1); 14264 return type + "-" + (option.getStartId() + 1); 14265 } else { 14266 long id = modelManager.DISPLAY_ID.get(type); 14267 modelManager.DISPLAY_ID.put(type, id + 1); 14268 return type + "-" + (id + 1); 14269 } 14270 } 14271 14272 private String getDisplayIdByTypeFromZero(String type) { 14273 if (!modelManager.DISPLAY_ID.containsKey(type)) { 14274 modelManager.DISPLAY_ID.put(type, option.getStartId()); 14275 if(option.getStartId() == 0) { 14276 return type; 14277 } 14278 return type + "-" + (option.getStartId() + 1); 14279 } else { 14280 long id = modelManager.DISPLAY_ID.get(type); 14281 modelManager.DISPLAY_ID.put(type, id + 1); 14282 return type + "-" + (id + 1); 14283 } 14284 } 14285 14286 private String getConstantName(Table tableModel) { 14287 if (modelManager.DISPLAY_NAME.containsKey(tableModel.getId())) { 14288 return modelManager.DISPLAY_NAME.get(tableModel.getId()); 14289 } else { 14290 String name = getDisplayIdByType("SQL_CONSTANTS"); 14291 modelManager.DISPLAY_NAME.put(tableModel.getId(), name); 14292 return name; 14293 } 14294 } 14295 14296 private String getTempTableName(TTable table) { 14297 if (modelManager.DISPLAY_NAME.containsKey((long)System.identityHashCode(table))) { 14298 return modelManager.DISPLAY_NAME.get((long)System.identityHashCode(table)); 14299 } else { 14300 String name = getDisplayIdByTypeFromZero(table.getName()); 14301 modelManager.DISPLAY_NAME.put((long)System.identityHashCode(table), name); 14302 return name; 14303 } 14304 } 14305 14306 private String getResultSetName(ResultSet resultSetModel) { 14307 14308 if (modelManager.DISPLAY_NAME.containsKey(resultSetModel.getId())) { 14309 return modelManager.DISPLAY_NAME.get(resultSetModel.getId()); 14310 } 14311 14312 if (resultSetModel.getGspObject() instanceof TFunctionCall && ((TFunctionCall)resultSetModel.getGspObject()).getFunctionType() == EFunctionType.array_t) { 14313 String name = getResultSetDisplayId("ARRAY"); 14314 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 14315 if(option.containsResultSetType(ResultSetType.array)) { 14316 resultSetModel.setTarget(true); 14317 } 14318 return name; 14319 } 14320 14321 if (resultSetModel.getGspObject() instanceof TFunctionCall && ((TFunctionCall)resultSetModel.getGspObject()).getFunctionType() == EFunctionType.struct_t) { 14322 String name = getResultSetDisplayId("STRUCT"); 14323 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 14324 if(option.containsResultSetType(ResultSetType.struct)) { 14325 resultSetModel.setTarget(true); 14326 } 14327 return name; 14328 } 14329 14330 if (resultSetModel instanceof QueryTable) { 14331 QueryTable table = (QueryTable) resultSetModel; 14332 if (table.getAlias() != null && table.getAlias().trim().length() > 0) { 14333 String name = getResultSetWithId("RESULT_OF_" + table.getAlias().trim()); 14334 if (table.getTableObject().getCTE() != null) { 14335 name = getResultSetWithId("RESULT_OF_" + table.getTableObject().getCTE().getTableName().toString() 14336 + "_" + table.getAlias().trim()); 14337 } 14338 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 14339 if(option.containsResultSetType(ResultSetType.result_of)) { 14340 resultSetModel.setTarget(true); 14341 } 14342 return name; 14343 } else if (table.getTableObject().getCTE() != null) { 14344 String name = getResultSetWithId("CTE-" + table.getTableObject().getCTE().getTableName().toString()); 14345 modelManager.DISPLAY_NAME.put(table.getId(), name); 14346 if(option.containsResultSetType(ResultSetType.cte)) { 14347 resultSetModel.setTarget(true); 14348 } 14349 return name; 14350 } 14351 } 14352 14353 if (resultSetModel instanceof SelectResultSet) { 14354 if (((SelectResultSet) resultSetModel).getSelectStmt().getParentStmt() instanceof TInsertSqlStatement) { 14355 String name = getResultSetDisplayId("INSERT-SELECT"); 14356 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 14357 if(option.containsResultSetType(ResultSetType.insert_select)) { 14358 resultSetModel.setTarget(true); 14359 } 14360 return name; 14361 } 14362 14363 if (((SelectResultSet) resultSetModel).getSelectStmt().getParentStmt() instanceof TUpdateSqlStatement) { 14364 String name = getResultSetDisplayId("UPDATE-SELECT"); 14365 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 14366 if(option.containsResultSetType(ResultSetType.update_select)) { 14367 resultSetModel.setTarget(true); 14368 } 14369 return name; 14370 } 14371 } 14372 14373 if (resultSetModel instanceof SelectSetResultSet) { 14374 ESetOperatorType type = ((SelectSetResultSet) resultSetModel).getSetOperatorType(); 14375 String name = getResultSetDisplayId("RESULT_OF_" + type.name().toUpperCase()); 14376 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 14377 if(option.containsResultSetType(ResultSetType.result_of)) { 14378 resultSetModel.setTarget(true); 14379 } 14380 return name; 14381 } 14382 14383 if (resultSetModel.getGspObject() instanceof TMergeUpdateClause) { 14384 String name = getResultSetDisplayId("MERGE-UPDATE"); 14385 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 14386 if(option.containsResultSetType(ResultSetType.merge_update)) { 14387 resultSetModel.setTarget(true); 14388 } 14389 return name; 14390 } 14391 14392 if (resultSetModel.getGspObject() instanceof TOutputClause) { 14393 String name = getResultSetDisplayId("OUTPUT"); 14394 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 14395 if(option.containsResultSetType(ResultSetType.output)) { 14396 resultSetModel.setTarget(true); 14397 } 14398 return name; 14399 } 14400 14401 if (resultSetModel.getGspObject() instanceof TMergeInsertClause) { 14402 String name = getResultSetDisplayId("MERGE-INSERT"); 14403 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 14404 if(option.containsResultSetType(ResultSetType.merge_insert)) { 14405 resultSetModel.setTarget(true); 14406 } 14407 return name; 14408 } 14409 14410 if (resultSetModel.getGspObject() instanceof TUpdateSqlStatement) { 14411 String name = getResultSetDisplayId("UPDATE-SET"); 14412 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 14413 if(option.containsResultSetType(ResultSetType.update_set)) { 14414 resultSetModel.setTarget(true); 14415 } 14416 return name; 14417 } 14418 14419 if (resultSetModel.getGspObject() instanceof TCaseExpression) { 14420 String name = ((Function) resultSetModel).getFunctionName(); 14421 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 14422 if (option.containsResultSetType(ResultSetType.case_when) || option.containsResultSetType(ResultSetType.function)) { 14423 resultSetModel.setTarget(true); 14424 } 14425 return name; 14426 } 14427 14428 if (resultSetModel.getGspObject() instanceof TFunctionCall || resultSetModel instanceof Function) { 14429 String name = ((Function) resultSetModel).getFunctionName(); 14430 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 14431 if(option.containsResultSetType(ResultSetType.function)) { 14432 resultSetModel.setTarget(true); 14433 } 14434 return name; 14435 } 14436 14437 if (resultSetModel instanceof PivotedTable) { 14438 String name = getResultSetDisplayId("PIVOT-TABLE"); 14439 if (((PivotedTable) resultSetModel).isUnpivoted()) { 14440 name = getResultSetDisplayId("UNPIVOT-TABLE"); 14441 if(option.containsResultSetType(ResultSetType.unpivot_table)) { 14442 resultSetModel.setTarget(true); 14443 } 14444 } 14445 else { 14446 if(option.containsResultSetType(ResultSetType.pivot_table)) { 14447 resultSetModel.setTarget(true); 14448 } 14449 } 14450 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 14451 return name; 14452 } 14453 14454 if (resultSetModel instanceof Alias) { 14455 String name = getResultSetDisplayId("ALIAS"); 14456 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 14457 if(option.containsResultSetType(ResultSetType.alias)) { 14458 resultSetModel.setTarget(true); 14459 } 14460 return name; 14461 } 14462 14463 String name = getResultSetDisplayId("RS"); 14464 modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name); 14465 if(option.containsResultSetType(ResultSetType.select_list)) { 14466 resultSetModel.setTarget(true); 14467 } 14468 return name; 14469 } 14470 14471 private String getResultSetWithId(String type) { 14472 type = DlineageUtil.getIdentifierNormalTableName(type); 14473 if (!modelManager.DISPLAY_ID.containsKey(type)) { 14474 modelManager.DISPLAY_ID.put(type, option.getStartId() + 1); 14475 return type + "-" + (option.getStartId() + 1); 14476 } else { 14477 long id = modelManager.DISPLAY_ID.get(type); 14478 modelManager.DISPLAY_ID.put(type, id + 1); 14479 return type + "-" + (id + 1); 14480 } 14481 } 14482 14483 private String getResultSetDisplayId(String type) { 14484 if (!modelManager.DISPLAY_ID.containsKey(type)) { 14485 modelManager.DISPLAY_ID.put(type, option.getStartId() + 1); 14486 return type + "-" + (option.getStartId() + 1); 14487 } else { 14488 long id = modelManager.DISPLAY_ID.get(type); 14489 modelManager.DISPLAY_ID.put(type, id + 1); 14490 return type + "-" + (id + 1); 14491 } 14492 } 14493 14494 private void appendViews(dataflow dataflow) { 14495 List<TCustomSqlStatement> views = modelManager.getViews(); 14496 for (int i = 0; i < views.size(); i++) { 14497 Table viewModel = (Table) modelManager.getViewModel(views.get(i)); 14498 if (!tableIds.contains(viewModel.getId())) { 14499 appendViewModel(dataflow, viewModel); 14500 tableIds.add(viewModel.getId()); 14501 } 14502 } 14503 14504 List<TTable> tables = modelManager.getBaseTables(); 14505 for (int i = 0; i < tables.size(); i++) { 14506 Object model = modelManager.getModel(tables.get(i)); 14507 if (model instanceof Table) { 14508 Table tableModel = (Table) model; 14509 if (tableModel.isView()) { 14510 if (!tableIds.contains(tableModel.getId())) { 14511 appendViewModel(dataflow, tableModel); 14512 tableIds.add(tableModel.getId()); 14513 } 14514 } 14515 } 14516 } 14517 14518 List<Table> tableNames = modelManager.getTablesByName(); 14519 for (int i = 0; i < tableNames.size(); i++) { 14520 Table tableModel = tableNames.get(i); 14521 if (tableModel.isView()) { 14522 if (!tableIds.contains(tableModel.getId())) { 14523 appendViewModel(dataflow, tableModel); 14524 tableIds.add(tableModel.getId()); 14525 } 14526 } 14527 } 14528 } 14529 14530 private void appendViewModel(dataflow dataflow, Table viewModel) { 14531 table viewElement = new table(); 14532 viewElement.setId(String.valueOf(viewModel.getId())); 14533 if (!SQLUtil.isEmpty(viewModel.getDatabase())) { 14534 viewElement.setDatabase(viewModel.getDatabase()); 14535 } 14536 if (!SQLUtil.isEmpty(viewModel.getSchema())) { 14537 viewElement.setSchema(viewModel.getSchema()); 14538 } 14539 viewElement.setServer(viewModel.getServer()); 14540 viewElement.setName(viewModel.getName()); 14541 viewElement.setType("view"); 14542 // Propagate the view sub type (e.g. temp_table for CREATE TEMPORARY VIEW) 14543 // so consumers can tell a temporary view apart from a regular one. Mantis 4538. 14544 if (viewModel.getSubType() != null) { 14545 viewElement.setSubType(viewModel.getSubType().name()); 14546 } 14547 viewElement.setStarStmt(viewModel.getStarStmt()); 14548 14549 if(viewModel.isFromDDL()){ 14550 viewElement.setFromDDL(String.valueOf(viewModel.isFromDDL())); 14551 } 14552 14553 if(option.isTraceTablePosition()){ 14554 for (Pair<Pair3<Long, Long, String>, Pair3<Long, Long, String>> position:viewModel.getPositions()){ 14555 viewElement.setCoordinate(convertCoordinate(position.first)+","+convertCoordinate(position.second)); 14556 } 14557 } 14558 else { 14559 viewElement.setCoordinate(convertCoordinate(viewModel.getStartPosition()) + "," 14560 + convertCoordinate(viewModel.getEndPosition())); 14561 } 14562 14563 if (viewModel.getProcesses() != null) { 14564 List<String> processIds = new ArrayList<String>(); 14565 for (Process process : viewModel.getProcesses()) { 14566 processIds.add(String.valueOf(process.getId())); 14567 } 14568 viewElement.setProcessIds(processIds); 14569 } 14570 dataflow.getViews().add(viewElement); 14571 14572 List<TableColumn> columns = viewModel.getColumns(); 14573 14574 if (containStarColumn(columns)) { 14575 for (TableColumn column : columns) { 14576 if (column.getName().endsWith("*")) { 14577 for (TableColumn starElement : columns) { 14578 if (starElement == column) { 14579 continue; 14580 } 14581 TObjectName columnObject = starElement.getColumnObject(); 14582 column.bindStarLinkColumn(columnObject); 14583 } 14584 if (viewModel.isCreateTable()) { 14585 column.setShowStar(false); 14586 } 14587 } 14588 } 14589 } 14590 14591 for (int j = 0; j < columns.size(); j++) { 14592 TableColumn columnModel = (TableColumn) columns.get(j); 14593 if (!columnModel.isPseduo() && columnModel.hasStarLinkColumn()) { 14594 List<String> starLinkColumnList = columnModel.getStarLinkColumnNames(); 14595 for (int k = 0; k < starLinkColumnList.size(); k++) { 14596 column columnElement = new column(); 14597 columnElement.setId(String.valueOf(columnModel.getId()) + "_" + k); 14598 String columnName = starLinkColumnList.get(k); 14599 if (containStarColumn(columns, columnName)) { 14600 continue; 14601 } 14602 columnElement.setName(columnName); 14603 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 14604 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 14605 + convertCoordinate(columnModel.getEndPosition())); 14606 } 14607 viewElement.getColumns().add(columnElement); 14608 } 14609 14610 if (columnModel.isShowStar()) { 14611 column columnElement = new column(); 14612 columnElement.setId(String.valueOf(columnModel.getId())); 14613 columnElement.setName(columnModel.getName()); 14614 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 14615 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 14616 + convertCoordinate(columnModel.getEndPosition())); 14617 } 14618 viewElement.getColumns().add(columnElement); 14619 } 14620 14621 } else { 14622 column columnElement = new column(); 14623 columnElement.setId(String.valueOf(columnModel.getId())); 14624 columnElement.setName(columnModel.getName()); 14625 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 14626 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 14627 + convertCoordinate(columnModel.getEndPosition())); 14628 } 14629 if(columnModel.isPseduo()) { 14630 columnElement.setSource("system"); 14631 } 14632 viewElement.getColumns().add(columnElement); 14633 } 14634 } 14635 14636 TableRelationRows relationRows = viewModel.getRelationRows(); 14637 if (relationRows.hasRelation()) { 14638 column relationRowsElement = new column(); 14639 relationRowsElement.setId(String.valueOf(relationRows.getId())); 14640 relationRowsElement.setName(relationRows.getName()); 14641 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 14642 relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 14643 + convertCoordinate(relationRows.getEndPosition())); 14644 } 14645 relationRowsElement.setSource("system"); 14646 viewElement.getColumns().add(relationRowsElement); 14647 } 14648 } 14649 14650 private void appendStreamModel(dataflow dataflow, Table streamModel) { 14651 table streamElement = new table(); 14652 streamElement.setId(String.valueOf(streamModel.getId())); 14653 if (!SQLUtil.isEmpty(streamModel.getDatabase())) { 14654 streamElement.setDatabase(streamModel.getDatabase()); 14655 } 14656 if (!SQLUtil.isEmpty(streamModel.getSchema())) { 14657 streamElement.setSchema(streamModel.getSchema()); 14658 } 14659 streamElement.setServer(streamModel.getServer()); 14660 streamElement.setName(streamModel.getName()); 14661 streamElement.setType("stream"); 14662 if (streamModel.getFileType() != null) { 14663 streamElement.setFileType(SQLUtil.trimColumnStringQuote(streamModel.getFileType())); 14664 } 14665 14666 if (streamModel.getStartPosition() != null && streamModel.getEndPosition() != null) { 14667 streamElement.setCoordinate(convertCoordinate(streamModel.getStartPosition()) + "," 14668 + convertCoordinate(streamModel.getEndPosition())); 14669 } 14670 14671 if (streamModel.getProcesses() != null) { 14672 List<String> processIds = new ArrayList<String>(); 14673 for (Process process : streamModel.getProcesses()) { 14674 processIds.add(String.valueOf(process.getId())); 14675 } 14676 streamElement.setProcessIds(processIds); 14677 } 14678 dataflow.getStreams().add(streamElement); 14679 14680 List<TableColumn> columns = streamModel.getColumns(); 14681 14682 for (int j = 0; j < columns.size(); j++) { 14683 TableColumn columnModel = (TableColumn) columns.get(j); 14684 column columnElement = new column(); 14685 columnElement.setId(String.valueOf(columnModel.getId())); 14686 columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName())); 14687 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 14688 + convertCoordinate(columnModel.getEndPosition())); 14689 streamElement.getColumns().add(columnElement); 14690 } 14691 14692 TableRelationRows relationRows = streamModel.getRelationRows(); 14693 if (relationRows.hasRelation()) { 14694 column relationRowsElement = new column(); 14695 relationRowsElement.setId(String.valueOf(relationRows.getId())); 14696 relationRowsElement.setName(relationRows.getName()); 14697 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 14698 relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 14699 + convertCoordinate(relationRows.getEndPosition())); 14700 } 14701 relationRowsElement.setSource("system"); 14702 streamElement.getColumns().add(relationRowsElement); 14703 } 14704 } 14705 14706 private void appendStageModel(dataflow dataflow, Table stageModel) { 14707 table stageElement = new table(); 14708 stageElement.setId(String.valueOf(stageModel.getId())); 14709 if (!SQLUtil.isEmpty(stageModel.getDatabase())) { 14710 stageElement.setDatabase(stageModel.getDatabase()); 14711 } 14712 if (!SQLUtil.isEmpty(stageModel.getSchema())) { 14713 stageElement.setSchema(stageModel.getSchema()); 14714 } 14715 stageElement.setServer(stageModel.getServer()); 14716 stageElement.setName(stageModel.getName()); 14717 stageElement.setType("stage"); 14718 stageElement.setLocation(stageModel.getLocation()); 14719 if (stageModel.getFileType() != null) { 14720 stageElement.setFileType(SQLUtil.trimColumnStringQuote(stageModel.getFileType())); 14721 } 14722 14723 if (stageModel.getStartPosition() != null && stageModel.getEndPosition() != null) { 14724 stageElement.setCoordinate(convertCoordinate(stageModel.getStartPosition()) + "," 14725 + convertCoordinate(stageModel.getEndPosition())); 14726 } 14727 14728 if (stageModel.getProcesses() != null) { 14729 List<String> processIds = new ArrayList<String>(); 14730 for (Process process : stageModel.getProcesses()) { 14731 processIds.add(String.valueOf(process.getId())); 14732 } 14733 stageElement.setProcessIds(processIds); 14734 } 14735 dataflow.getStages().add(stageElement); 14736 14737 List<TableColumn> columns = stageModel.getColumns(); 14738 14739 for (int j = 0; j < columns.size(); j++) { 14740 TableColumn columnModel = (TableColumn) columns.get(j); 14741 column columnElement = new column(); 14742 columnElement.setId(String.valueOf(columnModel.getId())); 14743 columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName())); 14744 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 14745 + convertCoordinate(columnModel.getEndPosition())); 14746 stageElement.getColumns().add(columnElement); 14747 } 14748 14749 TableRelationRows relationRows = stageModel.getRelationRows(); 14750 if (relationRows.hasRelation()) { 14751 column relationRowsElement = new column(); 14752 relationRowsElement.setId(String.valueOf(relationRows.getId())); 14753 relationRowsElement.setName(relationRows.getName()); 14754 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 14755 relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 14756 + convertCoordinate(relationRows.getEndPosition())); 14757 } 14758 relationRowsElement.setSource("system"); 14759 stageElement.getColumns().add(relationRowsElement); 14760 } 14761 } 14762 14763 private void appendSequenceModel(dataflow dataflow, Table sequenceModel) { 14764 table sequenceElement = new table(); 14765 sequenceElement.setId(String.valueOf(sequenceModel.getId())); 14766 if (!SQLUtil.isEmpty(sequenceModel.getDatabase())) { 14767 sequenceElement.setDatabase(sequenceModel.getDatabase()); 14768 } 14769 if (!SQLUtil.isEmpty(sequenceModel.getSchema())) { 14770 sequenceElement.setSchema(sequenceModel.getSchema()); 14771 } 14772 sequenceElement.setServer(sequenceModel.getServer()); 14773 sequenceElement.setName(sequenceModel.getName()); 14774 sequenceElement.setType("sequence"); 14775 sequenceElement.setLocation(sequenceModel.getLocation()); 14776 if (sequenceModel.getFileType() != null) { 14777 sequenceElement.setFileType(SQLUtil.trimColumnStringQuote(sequenceModel.getFileType())); 14778 } 14779 14780 if (sequenceModel.getStartPosition() != null && sequenceModel.getEndPosition() != null) { 14781 sequenceElement.setCoordinate(convertCoordinate(sequenceModel.getStartPosition()) + "," 14782 + convertCoordinate(sequenceModel.getEndPosition())); 14783 } 14784 14785 if (sequenceModel.getProcesses() != null) { 14786 List<String> processIds = new ArrayList<String>(); 14787 for (Process process : sequenceModel.getProcesses()) { 14788 processIds.add(String.valueOf(process.getId())); 14789 } 14790 sequenceElement.setProcessIds(processIds); 14791 } 14792 dataflow.getSequences().add(sequenceElement); 14793 14794 List<TableColumn> columns = sequenceModel.getColumns(); 14795 14796 for (int j = 0; j < columns.size(); j++) { 14797 TableColumn columnModel = (TableColumn) columns.get(j); 14798 column columnElement = new column(); 14799 columnElement.setId(String.valueOf(columnModel.getId())); 14800 columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName())); 14801 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 14802 + convertCoordinate(columnModel.getEndPosition())); 14803 sequenceElement.getColumns().add(columnElement); 14804 } 14805 14806 TableRelationRows relationRows = sequenceModel.getRelationRows(); 14807 if (relationRows.hasRelation()) { 14808 column relationRowsElement = new column(); 14809 relationRowsElement.setId(String.valueOf(relationRows.getId())); 14810 relationRowsElement.setName(relationRows.getName()); 14811 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 14812 relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 14813 + convertCoordinate(relationRows.getEndPosition())); 14814 } 14815 relationRowsElement.setSource("system"); 14816 sequenceElement.getColumns().add(relationRowsElement); 14817 } 14818 } 14819 14820 private void appendDataSourceModel(dataflow dataflow, Table datasourceModel) { 14821 table datasourceElement = new table(); 14822 datasourceElement.setId(String.valueOf(datasourceModel.getId())); 14823 if (!SQLUtil.isEmpty(datasourceModel.getDatabase())) { 14824 datasourceElement.setDatabase(datasourceModel.getDatabase()); 14825 } 14826 if (!SQLUtil.isEmpty(datasourceModel.getSchema())) { 14827 datasourceElement.setSchema(datasourceModel.getSchema()); 14828 } 14829 datasourceElement.setServer(datasourceModel.getServer()); 14830 datasourceElement.setName(datasourceModel.getName()); 14831 datasourceElement.setType("datasource"); 14832 datasourceElement.setLocation(datasourceModel.getLocation()); 14833 if (datasourceModel.getFileType() != null) { 14834 datasourceElement.setFileType(SQLUtil.trimColumnStringQuote(datasourceModel.getFileType())); 14835 } 14836 14837 if (datasourceModel.getStartPosition() != null && datasourceModel.getEndPosition() != null) { 14838 datasourceElement.setCoordinate(convertCoordinate(datasourceModel.getStartPosition()) + "," 14839 + convertCoordinate(datasourceModel.getEndPosition())); 14840 } 14841 14842 if (datasourceModel.getProcesses() != null) { 14843 List<String> processIds = new ArrayList<String>(); 14844 for (Process process : datasourceModel.getProcesses()) { 14845 processIds.add(String.valueOf(process.getId())); 14846 } 14847 datasourceElement.setProcessIds(processIds); 14848 } 14849 dataflow.getDatasources().add(datasourceElement); 14850 14851 List<TableColumn> columns = datasourceModel.getColumns(); 14852 14853 for (int j = 0; j < columns.size(); j++) { 14854 TableColumn columnModel = (TableColumn) columns.get(j); 14855 column columnElement = new column(); 14856 columnElement.setId(String.valueOf(columnModel.getId())); 14857 columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName())); 14858 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 14859 + convertCoordinate(columnModel.getEndPosition())); 14860 datasourceElement.getColumns().add(columnElement); 14861 } 14862 14863 TableRelationRows relationRows = datasourceModel.getRelationRows(); 14864 if (relationRows.hasRelation()) { 14865 column relationRowsElement = new column(); 14866 relationRowsElement.setId(String.valueOf(relationRows.getId())); 14867 relationRowsElement.setName(relationRows.getName()); 14868 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 14869 relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 14870 + convertCoordinate(relationRows.getEndPosition())); 14871 } 14872 relationRowsElement.setSource("system"); 14873 datasourceElement.getColumns().add(relationRowsElement); 14874 } 14875 } 14876 14877 private void appendDatabaseModel(dataflow dataflow, Table databaseModel) { 14878 table databaseElement = new table(); 14879 databaseElement.setId(String.valueOf(databaseModel.getId())); 14880 if (!SQLUtil.isEmpty(databaseModel.getDatabase())) { 14881 databaseElement.setDatabase(databaseModel.getDatabase()); 14882 } 14883 if (!SQLUtil.isEmpty(databaseModel.getSchema())) { 14884 databaseElement.setSchema(databaseModel.getSchema()); 14885 } 14886 databaseElement.setServer(databaseModel.getServer()); 14887 databaseElement.setName(databaseModel.getName()); 14888 databaseElement.setType("database"); 14889 if (databaseModel.getFileType() != null) { 14890 databaseElement.setFileType(SQLUtil.trimColumnStringQuote(databaseModel.getFileType())); 14891 } 14892 14893 if (databaseModel.getStartPosition() != null && databaseModel.getEndPosition() != null) { 14894 databaseElement.setCoordinate(convertCoordinate(databaseModel.getStartPosition()) + "," 14895 + convertCoordinate(databaseModel.getEndPosition())); 14896 } 14897 14898 if (databaseModel.getProcesses() != null) { 14899 List<String> processIds = new ArrayList<String>(); 14900 for (Process process : databaseModel.getProcesses()) { 14901 processIds.add(String.valueOf(process.getId())); 14902 } 14903 databaseElement.setProcessIds(processIds); 14904 } 14905 dataflow.getDatabases().add(databaseElement); 14906 14907 List<TableColumn> columns = databaseModel.getColumns(); 14908 14909 for (int j = 0; j < columns.size(); j++) { 14910 TableColumn columnModel = (TableColumn) columns.get(j); 14911 column columnElement = new column(); 14912 columnElement.setId(String.valueOf(columnModel.getId())); 14913 columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName())); 14914 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 14915 + convertCoordinate(columnModel.getEndPosition())); 14916 databaseElement.getColumns().add(columnElement); 14917 } 14918 14919 TableRelationRows relationRows = databaseModel.getRelationRows(); 14920 if (relationRows.hasRelation()) { 14921 column relationRowsElement = new column(); 14922 relationRowsElement.setId(String.valueOf(relationRows.getId())); 14923 relationRowsElement.setName(relationRows.getName()); 14924 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 14925 relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 14926 + convertCoordinate(relationRows.getEndPosition())); 14927 } 14928 relationRowsElement.setSource("system"); 14929 databaseElement.getColumns().add(relationRowsElement); 14930 } 14931 } 14932 14933 private void appendSchemaModel(dataflow dataflow, Table schemaModel) { 14934 table schemaElement = new table(); 14935 schemaElement.setId(String.valueOf(schemaModel.getId())); 14936 if (!SQLUtil.isEmpty(schemaModel.getDatabase())) { 14937 schemaElement.setDatabase(schemaModel.getDatabase()); 14938 } 14939 if (!SQLUtil.isEmpty(schemaModel.getSchema())) { 14940 schemaElement.setSchema(schemaModel.getSchema()); 14941 } 14942 schemaElement.setServer(schemaModel.getServer()); 14943 schemaElement.setName(schemaModel.getName()); 14944 schemaElement.setType("schema"); 14945 if (schemaModel.getFileType() != null) { 14946 schemaElement.setFileType(SQLUtil.trimColumnStringQuote(schemaModel.getFileType())); 14947 } 14948 14949 if (schemaModel.getStartPosition() != null && schemaModel.getEndPosition() != null) { 14950 schemaElement.setCoordinate(convertCoordinate(schemaModel.getStartPosition()) + "," 14951 + convertCoordinate(schemaModel.getEndPosition())); 14952 } 14953 14954 if (schemaModel.getProcesses() != null) { 14955 List<String> processIds = new ArrayList<String>(); 14956 for (Process process : schemaModel.getProcesses()) { 14957 processIds.add(String.valueOf(process.getId())); 14958 } 14959 schemaElement.setProcessIds(processIds); 14960 } 14961 dataflow.getSchemas().add(schemaElement); 14962 14963 List<TableColumn> columns = schemaModel.getColumns(); 14964 14965 for (int j = 0; j < columns.size(); j++) { 14966 TableColumn columnModel = (TableColumn) columns.get(j); 14967 column columnElement = new column(); 14968 columnElement.setId(String.valueOf(columnModel.getId())); 14969 columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName())); 14970 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 14971 + convertCoordinate(columnModel.getEndPosition())); 14972 schemaElement.getColumns().add(columnElement); 14973 } 14974 14975 TableRelationRows relationRows = schemaModel.getRelationRows(); 14976 if (relationRows.hasRelation()) { 14977 column relationRowsElement = new column(); 14978 relationRowsElement.setId(String.valueOf(relationRows.getId())); 14979 relationRowsElement.setName(relationRows.getName()); 14980 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 14981 relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 14982 + convertCoordinate(relationRows.getEndPosition())); 14983 } 14984 relationRowsElement.setSource("system"); 14985 schemaElement.getColumns().add(relationRowsElement); 14986 } 14987 } 14988 14989 private void appendPathModel(dataflow dataflow, Table pathModel) { 14990 table pathElement = new table(); 14991 pathElement.setId(String.valueOf(pathModel.getId())); 14992 if (!SQLUtil.isEmpty(pathModel.getDatabase())) { 14993 pathElement.setDatabase(pathModel.getDatabase()); 14994 } 14995 if (!SQLUtil.isEmpty(pathModel.getSchema())) { 14996 pathElement.setSchema(pathModel.getSchema()); 14997 } 14998 pathElement.setServer(pathModel.getServer()); 14999 pathElement.setName(pathModel.getName()); 15000 pathElement.setType("path"); 15001 if (pathModel.getFileFormat() != null) { 15002 pathElement.setFileFormat(SQLUtil.trimColumnStringQuote(pathModel.getFileFormat())); 15003 } 15004 15005 if (pathModel.getStartPosition() != null && pathModel.getEndPosition() != null) { 15006 pathElement.setCoordinate(convertCoordinate(pathModel.getStartPosition()) + "," 15007 + convertCoordinate(pathModel.getEndPosition())); 15008 } 15009 15010 if (pathModel.getProcesses() != null) { 15011 List<String> processIds = new ArrayList<String>(); 15012 for (Process process : pathModel.getProcesses()) { 15013 processIds.add(String.valueOf(process.getId())); 15014 } 15015 pathElement.setProcessIds(processIds); 15016 } 15017 15018 pathElement.setUri(pathModel.getName()); 15019 15020 dataflow.getPaths().add(pathElement); 15021 15022 List<TableColumn> columns = pathModel.getColumns(); 15023 15024 for (int j = 0; j < columns.size(); j++) { 15025 TableColumn columnModel = (TableColumn) columns.get(j); 15026 column columnElement = new column(); 15027 columnElement.setId(String.valueOf(columnModel.getId())); 15028 columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName())); 15029 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 15030 + convertCoordinate(columnModel.getEndPosition())); 15031 pathElement.getColumns().add(columnElement); 15032 } 15033 15034 TableRelationRows relationRows = pathModel.getRelationRows(); 15035 if (relationRows.hasRelation()) { 15036 column relationRowsElement = new column(); 15037 relationRowsElement.setId(String.valueOf(relationRows.getId())); 15038 relationRowsElement.setName(relationRows.getName()); 15039 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 15040 relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 15041 + convertCoordinate(relationRows.getEndPosition())); 15042 } 15043 relationRowsElement.setSource("system"); 15044 pathElement.getColumns().add(relationRowsElement); 15045 } 15046 } 15047 15048 private void appendVariableModel(dataflow dataflow, Table variableModel) { 15049 table variableElement = new table(); 15050 variableElement.setId(String.valueOf(variableModel.getId())); 15051 if (!SQLUtil.isEmpty(variableModel.getDatabase())) { 15052 variableElement.setDatabase(variableModel.getDatabase()); 15053 } 15054 if (!SQLUtil.isEmpty(variableModel.getSchema())) { 15055 variableElement.setSchema(variableModel.getSchema()); 15056 } 15057 variableElement.setServer(variableModel.getServer()); 15058 variableElement.setName(variableModel.getName()); 15059 variableElement.setType("variable"); 15060 variableElement.setParent(variableModel.getParent()); 15061 if (variableModel.getSubType() != null) { 15062 variableElement.setSubType(variableModel.getSubType().name()); 15063 } 15064 15065 if (variableModel.getStartPosition() != null && variableModel.getEndPosition() != null) { 15066 variableElement.setCoordinate(convertCoordinate(variableModel.getStartPosition()) + "," 15067 + convertCoordinate(variableModel.getEndPosition())); 15068 } 15069 dataflow.getVariables().add(variableElement); 15070 15071 List<TableColumn> columns = variableModel.getColumns(); 15072 15073 if (containStarColumn(columns)) { 15074 for (TableColumn column : columns) { 15075 if (column.getName().endsWith("*")) { 15076 for (TableColumn starElement : columns) { 15077 if (starElement == column) { 15078 continue; 15079 } 15080 TObjectName columnObject = starElement.getColumnObject(); 15081 column.bindStarLinkColumn(columnObject); 15082 } 15083// column.setShowStar(false); 15084 } 15085 } 15086 } 15087 15088 for (int j = 0; j < columns.size(); j++) { 15089 TableColumn columnModel = columns.get(j); 15090 if (columnModel.hasStarLinkColumn()) { 15091 List<String> starLinkColumnList = columnModel.getStarLinkColumnNames(); 15092 for (int k = 0; k < starLinkColumnList.size(); k++) { 15093 column columnElement = new column(); 15094 columnElement.setId(columnModel.getId() + "_" + k); 15095 String columnName = starLinkColumnList.get(k); 15096 if (containStarColumn(columns, columnName)) { 15097 continue; 15098 } 15099 columnElement.setName(columnName); 15100 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 15101 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 15102 + convertCoordinate(columnModel.getEndPosition())); 15103 } 15104 variableElement.getColumns().add(columnElement); 15105 } 15106 15107 if (columnModel.isShowStar()) { 15108 column columnElement = new column(); 15109 columnElement.setId(String.valueOf(columnModel.getId())); 15110 columnElement.setName(columnModel.getName()); 15111 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 15112 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 15113 + convertCoordinate(columnModel.getEndPosition())); 15114 } 15115 variableElement.getColumns().add(columnElement); 15116 } 15117 15118 } else { 15119 column columnElement = new column(); 15120 columnElement.setId(String.valueOf(columnModel.getId())); 15121 columnElement.setName(columnModel.getName()); 15122 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 15123 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 15124 + convertCoordinate(columnModel.getEndPosition())); 15125 } 15126 variableElement.getColumns().add(columnElement); 15127 } 15128 } 15129 15130 TableRelationRows relationRows = variableModel.getRelationRows(); 15131 if (relationRows.hasRelation()) { 15132 column relationRowsElement = new column(); 15133 relationRowsElement.setId(String.valueOf(relationRows.getId())); 15134 relationRowsElement.setName(relationRows.getName()); 15135 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 15136 relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 15137 + convertCoordinate(relationRows.getEndPosition())); 15138 } 15139 relationRowsElement.setSource("system"); 15140 variableElement.getColumns().add(relationRowsElement); 15141 } 15142 } 15143 15144 private void appendCursorModel(dataflow dataflow, Table cursorModel) { 15145 table cursorElement = new table(); 15146 cursorElement.setId(String.valueOf(cursorModel.getId())); 15147 if (!SQLUtil.isEmpty(cursorModel.getDatabase())) { 15148 cursorElement.setDatabase(cursorModel.getDatabase()); 15149 } 15150 if (!SQLUtil.isEmpty(cursorModel.getSchema())) { 15151 cursorElement.setSchema(cursorModel.getSchema()); 15152 } 15153 cursorElement.setServer(cursorModel.getServer()); 15154 cursorElement.setName(cursorModel.getName()); 15155 cursorElement.setType("variable"); 15156 if (cursorElement.getSubType() != null) { 15157 cursorElement.setSubType(cursorModel.getSubType().name()); 15158 } 15159 15160 if (cursorModel.getStartPosition() != null && cursorModel.getEndPosition() != null) { 15161 cursorElement.setCoordinate(convertCoordinate(cursorModel.getStartPosition()) + "," 15162 + convertCoordinate(cursorModel.getEndPosition())); 15163 } 15164 dataflow.getVariables().add(cursorElement); 15165 15166 List<TableColumn> columns = cursorModel.getColumns(); 15167 15168 if (containStarColumn(columns)) { 15169 for (TableColumn column : columns) { 15170 if (column.getName().endsWith("*")) { 15171 for (TableColumn starElement : columns) { 15172 if (starElement == column) { 15173 continue; 15174 } 15175 TObjectName columnObject = starElement.getColumnObject(); 15176 column.bindStarLinkColumn(columnObject); 15177 } 15178 column.setShowStar(false); 15179 } 15180 } 15181 } 15182 15183 for (int j = 0; j < columns.size(); j++) { 15184 TableColumn columnModel = (TableColumn) columns.get(j); 15185 if (columnModel.hasStarLinkColumn()) { 15186 List<String> starLinkColumnList = columnModel.getStarLinkColumnNames(); 15187 for (int k = 0; k < starLinkColumnList.size(); k++) { 15188 column columnElement = new column(); 15189 columnElement.setId(String.valueOf(columnModel.getId()) + "_" + k); 15190 String columnName = starLinkColumnList.get(k); 15191 if (containStarColumn(columns, columnName)) { 15192 continue; 15193 } 15194 columnElement.setName(columnName); 15195 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 15196 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 15197 + convertCoordinate(columnModel.getEndPosition())); 15198 } 15199 cursorElement.getColumns().add(columnElement); 15200 } 15201 15202 if (columnModel.isShowStar()) { 15203 column columnElement = new column(); 15204 columnElement.setId(String.valueOf(columnModel.getId())); 15205 columnElement.setName(columnModel.getName()); 15206 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 15207 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 15208 + convertCoordinate(columnModel.getEndPosition())); 15209 } 15210 cursorElement.getColumns().add(columnElement); 15211 } 15212 15213 } else { 15214 column columnElement = new column(); 15215 columnElement.setId(String.valueOf(columnModel.getId())); 15216 columnElement.setName(columnModel.getName()); 15217 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 15218 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 15219 + convertCoordinate(columnModel.getEndPosition())); 15220 } 15221 cursorElement.getColumns().add(columnElement); 15222 } 15223 } 15224 15225 TableRelationRows relationRows = cursorModel.getRelationRows(); 15226 if (relationRows.hasRelation()) { 15227 column relationRowsElement = new column(); 15228 relationRowsElement.setId(String.valueOf(relationRows.getId())); 15229 relationRowsElement.setName(relationRows.getName()); 15230 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 15231 relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 15232 + convertCoordinate(relationRows.getEndPosition())); 15233 } 15234 relationRowsElement.setSource("system"); 15235 cursorElement.getColumns().add(relationRowsElement); 15236 } 15237 } 15238 15239 private void appendErrors(dataflow dataflow) { 15240 List<ErrorInfo> errorInfos = this.getErrorMessages(); 15241 if (metadataErrors != null) { 15242 for (int i = 0; i < metadataErrors.size(); i++) { 15243 errorInfos.add(i, metadataErrors.get(i)); 15244 } 15245 } 15246 15247 for (int i = 0; i < errorInfos.size(); ++i) { 15248 ErrorInfo errorInfo = errorInfos.get(i); 15249 error error = new error(); 15250 if (!SQLUtil.isEmpty(errorInfo.getErrorMessage())) { 15251 error.setErrorMessage(errorInfo.getErrorMessage()); 15252 } 15253 if (!SQLUtil.isEmpty(errorInfo.getErrorType())) { 15254 error.setErrorType(errorInfo.getErrorType()); 15255 } 15256 if (errorInfo.getStartPosition() != null && errorInfo.getEndPosition() != null) { 15257 error.setCoordinate(convertCoordinate(errorInfo.getStartPosition()) + "," 15258 + convertCoordinate(errorInfo.getEndPosition())); 15259 } 15260 if (!SQLUtil.isEmpty(errorInfo.getFileName())) { 15261 error.setFile(errorInfo.getFileName()); 15262 } 15263 if (errorInfo.getOriginStartPosition() != null && errorInfo.getOriginEndPosition() != null) { 15264 error.setOriginCoordinate(errorInfo.getOriginStartPosition() + "," + errorInfo.getOriginEndPosition()); 15265 } 15266 dataflow.getErrors().add(error); 15267 } 15268 } 15269 15270 private void appendOraclePackages(dataflow dataflow) { 15271 List<OraclePackage> packages = this.modelManager.getOraclePackageModels(); 15272 15273 for (int i = 0; i < packages.size(); ++i) { 15274 OraclePackage model = packages.get(i); 15275 oraclePackage oraclePackage = new oraclePackage(); 15276 oraclePackage.setId(String.valueOf(model.getId())); 15277 if (!SQLUtil.isEmpty(model.getDatabase())) { 15278 oraclePackage.setDatabase(model.getDatabase()); 15279 } 15280 if (!SQLUtil.isEmpty(model.getSchema())) { 15281 oraclePackage.setSchema(model.getSchema()); 15282 } 15283 oraclePackage.setServer(model.getServer()); 15284 oraclePackage.setName(model.getName()); 15285 if (model.getType() != null) { 15286 oraclePackage.setType(model.getType().name().replace("sst", "")); 15287 } 15288 if (model.getStartPosition() != null && model.getEndPosition() != null) { 15289 oraclePackage.setCoordinate( 15290 convertCoordinate(model.getStartPosition()) + "," + convertCoordinate(model.getEndPosition())); 15291 } 15292 15293 dataflow.getPackages().add(oraclePackage); 15294 15295 List<Argument> arguments = model.getArguments(); 15296 15297 for (int j = 0; j < arguments.size(); ++j) { 15298 Argument argumentModel = (Argument) arguments.get(j); 15299 argument argumentElement = new argument(); 15300 argumentElement.setId(String.valueOf(argumentModel.getId())); 15301 argumentElement.setName(argumentModel.getName()); 15302 if (argumentModel.getStartPosition() != null && argumentModel.getEndPosition() != null) { 15303 argumentElement.setCoordinate(convertCoordinate(argumentModel.getStartPosition()) + "," 15304 + convertCoordinate(argumentModel.getEndPosition())); 15305 } 15306 15307 argumentElement.setDatatype(argumentModel.getDataType().getDataTypeName()); 15308 argumentElement.setInout(argumentModel.getMode().name()); 15309 oraclePackage.getArguments().add(argumentElement); 15310 } 15311 15312 for (int j = 0; j < model.getProcedures().size(); j++) { 15313 Procedure procedureModel = model.getProcedures().get(j); 15314 procedure procedure = new procedure(); 15315 procedure.setId(String.valueOf(procedureModel.getId())); 15316 if (!SQLUtil.isEmpty(procedureModel.getDatabase())) { 15317 procedure.setDatabase(procedureModel.getDatabase()); 15318 } 15319 if (!SQLUtil.isEmpty(procedureModel.getSchema())) { 15320 procedure.setSchema(procedureModel.getSchema()); 15321 } 15322 procedure.setServer(procedureModel.getServer()); 15323 procedure.setName(procedureModel.getName()); 15324 if (procedureModel.getType() != null) { 15325 procedure.setType(procedureModel.getType().name().replace("sst", "")); 15326 } 15327 if (procedureModel.getStartPosition() != null && procedureModel.getEndPosition() != null) { 15328 procedure.setCoordinate(convertCoordinate(procedureModel.getStartPosition()) + "," 15329 + convertCoordinate(procedureModel.getEndPosition())); 15330 } 15331 15332 oraclePackage.getProcedures().add(procedure); 15333 15334 List<Argument> procedureArguments = procedureModel.getArguments(); 15335 15336 for (int k = 0; k < procedureArguments.size(); ++k) { 15337 Argument argumentModel = (Argument) procedureArguments.get(k); 15338 argument argumentElement = new argument(); 15339 argumentElement.setId(String.valueOf(argumentModel.getId())); 15340 argumentElement.setName(argumentModel.getName()); 15341 if (argumentModel.getStartPosition() != null && argumentModel.getEndPosition() != null) { 15342 argumentElement.setCoordinate(convertCoordinate(argumentModel.getStartPosition()) + "," 15343 + convertCoordinate(argumentModel.getEndPosition())); 15344 } 15345 15346 argumentElement.setDatatype(argumentModel.getDataType().getDataTypeName()); 15347 argumentElement.setInout(argumentModel.getMode().name()); 15348 procedure.getArguments().add(argumentElement); 15349 } 15350 } 15351 } 15352 } 15353 15354 private void appendProcedures(dataflow dataflow) { 15355 List<Procedure> procedures = this.modelManager.getProcedureModels(); 15356 15357 for (int i = 0; i < procedures.size(); ++i) { 15358 Procedure model = procedures.get(i); 15359 if (model.getParentPackage() != null) { 15360 continue; 15361 } 15362 procedure procedure = new procedure(); 15363 procedure.setId(String.valueOf(model.getId())); 15364 if (!SQLUtil.isEmpty(model.getDatabase())) { 15365 procedure.setDatabase(model.getDatabase()); 15366 } 15367 if (!SQLUtil.isEmpty(model.getSchema())) { 15368 procedure.setSchema(model.getSchema()); 15369 } 15370 procedure.setServer(model.getServer()); 15371 procedure.setName(model.getName()); 15372 if (model.getType() != null) { 15373 procedure.setType(model.getType().name().replace("sst", "")); 15374 } 15375 if (model.getStartPosition() != null && model.getEndPosition() != null) { 15376 procedure.setCoordinate( 15377 convertCoordinate(model.getStartPosition()) + "," + convertCoordinate(model.getEndPosition())); 15378 } 15379 15380 dataflow.getProcedures().add(procedure); 15381 15382 List<Argument> arguments = model.getArguments(); 15383 15384 for (int j = 0; j < arguments.size(); ++j) { 15385 Argument argumentModel = (Argument) arguments.get(j); 15386 argument argumentElement = new argument(); 15387 argumentElement.setId(String.valueOf(argumentModel.getId())); 15388 argumentElement.setName(argumentModel.getName()); 15389 if (argumentModel.getStartPosition() != null && argumentModel.getEndPosition() != null) { 15390 argumentElement.setCoordinate(convertCoordinate(argumentModel.getStartPosition()) + "," 15391 + convertCoordinate(argumentModel.getEndPosition())); 15392 } 15393 15394 argumentElement.setDatatype(argumentModel.getDataType().getDataTypeName()); 15395 argumentElement.setInout(argumentModel.getMode().name()); 15396 procedure.getArguments().add(argumentElement); 15397 } 15398 } 15399 } 15400 15401 private void appendProcesses(dataflow dataflow) { 15402 List<Process> processes = this.modelManager.getProcessModels(); 15403 15404 for (int i = 0; i < processes.size(); ++i) { 15405 Process model = processes.get(i); 15406 process process = new process(); 15407 process.setId(String.valueOf(model.getId())); 15408 if (!SQLUtil.isEmpty(model.getDatabase())) { 15409 process.setDatabase(model.getDatabase()); 15410 } 15411 if (!SQLUtil.isEmpty(model.getSchema())) { 15412 process.setSchema(model.getSchema()); 15413 } 15414 process.setServer(model.getServer()); 15415 process.setName(getProcessName(model)); 15416 if (!SQLUtil.isEmpty(model.getProcedureName())) { 15417 process.setProcedureName(model.getProcedureName()); 15418 } 15419 if (model.getProcedureId() != null) { 15420 process.setProcedureId(String.valueOf(model.getProcedureId())); 15421 } 15422 if (!SQLUtil.isEmpty(model.getQueryHashId())) { 15423 process.setQueryHashId(model.getQueryHashId()); 15424 } 15425 if (model.getGspObject() != null) { 15426 process.setType(model.getGspObject().sqlstatementtype.name()); 15427 } 15428 if (model.getStartPosition() != null && model.getEndPosition() != null) { 15429 process.setCoordinate( 15430 convertCoordinate(model.getStartPosition()) + "," + convertCoordinate(model.getEndPosition())); 15431 } 15432 if (model.getTransforms() != null && !model.getTransforms().isEmpty()) { 15433 for (Transform transformItem : model.getTransforms()) { 15434 process.addTransform(transformItem); 15435 } 15436 } 15437 dataflow.getProcesses().add(process); 15438 } 15439 } 15440 15441 private void appendTables(dataflow dataflow) { 15442 List<TTable> tables = modelManager.getBaseTables(); 15443 Map<String, table> tableMap = new HashMap<String, table>(); 15444 Set<Long> tableModelIds = new HashSet<Long>(); 15445 for (int i = 0; i < tables.size(); i++) { 15446 Object model = modelManager.getModel(tables.get(i)); 15447 if (model instanceof Table) { 15448 Table tableModel = (Table) model; 15449 if(tableModelIds.contains(tableModel.getId())) { 15450 continue; 15451 } 15452 else { 15453 tableModelIds.add(tableModel.getId()); 15454 } 15455 if (tableModel.isView()) { 15456 continue; 15457 } 15458 if (tableModel.isStage()) { 15459 appendStageModel(dataflow, tableModel); 15460 continue; 15461 } 15462 if (tableModel.isSequence()) { 15463 appendSequenceModel(dataflow, tableModel); 15464 continue; 15465 } 15466 if (tableModel.isDataSource()) { 15467 appendDataSourceModel(dataflow, tableModel); 15468 continue; 15469 } 15470 if (tableModel.isDatabase()) { 15471 appendDatabaseModel(dataflow, tableModel); 15472 continue; 15473 } 15474 if (tableModel.isSchema()) { 15475 appendSchemaModel(dataflow, tableModel); 15476 continue; 15477 } 15478 if (tableModel.isStream()) { 15479 appendStreamModel(dataflow, tableModel); 15480 continue; 15481 } 15482 if (tableModel.isPath()) { 15483 appendPathModel(dataflow, tableModel); 15484 continue; 15485 } 15486 if (tableModel.isVariable() && !tableModel.isCursor()) { 15487 appendVariableModel(dataflow, tableModel); 15488 continue; 15489 } 15490 if (tableModel.isCursor()) { 15491 appendCursorModel(dataflow, tableModel); 15492 continue; 15493 } 15494 if (tableModel.isConstant()) { 15495 appendConstantModel(dataflow, tableModel); 15496 continue; 15497 } 15498 if (!tableIds.contains(tableModel.getId())) { 15499 appendTableModel(dataflow, tableModel, tableMap); 15500 tableIds.add(tableModel.getId()); 15501 } 15502 } else if (model instanceof QueryTable) { 15503 QueryTable queryTable = (QueryTable) model; 15504 if (!tableIds.contains(queryTable.getId())) { 15505 appendResultSet(dataflow, queryTable); 15506 tableIds.add(queryTable.getId()); 15507 } 15508 } 15509 } 15510 15511 List<Table> tableNames = modelManager.getTablesByName(); 15512 tableNames.addAll(modelManager.getDropTables()); 15513 15514 for (int i = 0; i < tableNames.size(); i++) { 15515 Table tableModel = tableNames.get(i); 15516 if(tableModelIds.contains(tableModel.getId())) { 15517 continue; 15518 } 15519 else { 15520 tableModelIds.add(tableModel.getId()); 15521 } 15522 if (tableModel.isView()) { 15523 continue; 15524 } 15525 if (tableModel.isDatabase()) { 15526 appendDatabaseModel(dataflow, tableModel); 15527 continue; 15528 } 15529 if (tableModel.isSchema()) { 15530 appendSchemaModel(dataflow, tableModel); 15531 continue; 15532 } 15533 if (tableModel.isStage()) { 15534 appendStageModel(dataflow, tableModel); 15535 continue; 15536 } 15537 if (tableModel.isSequence()) { 15538 appendSequenceModel(dataflow, tableModel); 15539 continue; 15540 } 15541 if (tableModel.isDataSource()) { 15542 appendDataSourceModel(dataflow, tableModel); 15543 continue; 15544 } 15545 if (tableModel.isStream()) { 15546 appendStreamModel(dataflow, tableModel); 15547 continue; 15548 } 15549 if (tableModel.isPath()) { 15550 appendPathModel(dataflow, tableModel); 15551 continue; 15552 } 15553 if (tableModel.isVariable()) { 15554 appendVariableModel(dataflow, tableModel); 15555 continue; 15556 } 15557 if (tableModel.isCursor()) { 15558 appendCursorModel(dataflow, tableModel); 15559 continue; 15560 } 15561 if (tableModel.isConstant()) { 15562 appendConstantModel(dataflow, tableModel); 15563 continue; 15564 } 15565 if (!tableIds.contains(tableModel.getId())) { 15566 appendTableModel(dataflow, tableModel, tableMap); 15567 tableIds.add(tableModel.getId()); 15568 } 15569 } 15570 } 15571 15572 private void appendConstantModel(dataflow dataflow, Table tableModel) { 15573 table constantElement = new table(); 15574 constantElement.setId(String.valueOf(tableModel.getId())); 15575 if (!SQLUtil.isEmpty(tableModel.getDatabase())) { 15576 constantElement.setDatabase(tableModel.getDatabase()); 15577 } 15578 if (!SQLUtil.isEmpty(tableModel.getSchema())) { 15579 constantElement.setSchema(tableModel.getSchema()); 15580 } 15581 constantElement.setServer(tableModel.getServer()); 15582 constantElement.setName(getConstantName(tableModel)); 15583 constantElement.setType("constantTable"); 15584 15585 if (tableModel.getStartPosition() != null && tableModel.getEndPosition() != null) { 15586 constantElement.setCoordinate(convertCoordinate(tableModel.getStartPosition()) + "," 15587 + convertCoordinate(tableModel.getEndPosition())); 15588 } 15589 dataflow.getTables().add(constantElement); 15590 15591 List<TableColumn> columns = tableModel.getColumns(); 15592 for (int j = 0; j < columns.size(); j++) { 15593 TableColumn columnModel = (TableColumn) columns.get(j); 15594 column columnElement = new column(); 15595 columnElement.setId(String.valueOf(columnModel.getId())); 15596 columnElement.setName(columnModel.getName()); 15597 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 15598 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 15599 + convertCoordinate(columnModel.getEndPosition())); 15600 } 15601 constantElement.getColumns().add(columnElement); 15602 } 15603 } 15604 15605 /** 15606 * Copies the authoritative endpoint classification from the internal model onto the 15607 * XML element, emitting each field ONLY when it carries information (kind/intro not 15608 * UNKNOWN, createdInSql only when true, normalizedName only when it differs from the 15609 * raw name). This keeps existing XML byte-identical for endpoints that aren't 15610 * classified, honouring the strictly-additive contract (§9 of 15611 * docs/tmp/dlineage-authoritative-endpoint-classification.md). 15612 */ 15613 private void appendEndpointClassification(table tableElement, Table tableModel) { 15614 boolean created = tableModel.isCreatedInSql(); 15615 EndpointKind kind = tableModel.getEndpointKind(); 15616 // Emit endpointKind only when it carries signal: a non-catalog special kind 15617 // (temp / global-temp / table-variable / tempdb) always, or CATALOG_OBJECT only 15618 // when the object is created here. A plainly-referenced catalog table is the 15619 // default case and carries no attribute, so existing golden XML for ordinary 15620 // table references stays byte-identical. 15621 if (kind != null && kind != EndpointKind.UNKNOWN 15622 && (created || kind != EndpointKind.CATALOG_OBJECT)) { 15623 tableElement.setEndpointKind(kind.name()); 15624 } 15625 EndpointIntroduction intro = tableModel.getEndpointIntroduction(); 15626 if (intro != null && intro != EndpointIntroduction.UNKNOWN) { 15627 tableElement.setEndpointIntroduction(intro.name()); 15628 } 15629 if (created) { 15630 tableElement.setCreatedInSql("true"); 15631 } 15632 // Emit normalizedName only when the raw name actually carries delimiters 15633 // (brackets / quotes / backticks) — that is when the normalized form is useful 15634 // and not trivially derivable. Avoids case-only churn on every plain name. 15635 String rawName = tableModel.getName(); 15636 if (rawName != null && hasIdentifierDelimiter(rawName)) { 15637 String normalized = tableModel.getNormalizedName(); 15638 if (normalized != null && !normalized.equals(rawName)) { 15639 tableElement.setNormalizedName(normalized); 15640 } 15641 } 15642 } 15643 15644 private static boolean hasIdentifierDelimiter(String name) { 15645 return name.indexOf('[') != -1 || name.indexOf(']') != -1 15646 || name.indexOf('`') != -1 || name.indexOf('"') != -1; 15647 } 15648 15649 private void appendTableModel(dataflow dataflow, Table tableModel, Map<String, table> tableMap) { 15650 if(tableModel.getSubType() == SubType.unnest) {} 15651 table tableElement = new table(); 15652 tableElement.setId(String.valueOf(tableModel.getId())); 15653 // A one-part name that is ambiguous across two or more schemas (with no object 15654 // in the default schema) must NOT be bound to a fabricated default-schema 15655 // object: surface it unqualified and expose the candidate set instead. 15656 boolean ambiguousUnqualified = tableModel.isAmbiguousUnqualifiedTable() 15657 && tableModel.getCandidateTables() != null 15658 && !tableModel.getCandidateTables().isEmpty(); 15659 if (!ambiguousUnqualified) { 15660 if (!SQLUtil.isEmpty(tableModel.getDatabase())) { 15661 tableElement.setDatabase(tableModel.getDatabase()); 15662 } 15663 if (!SQLUtil.isEmpty(tableModel.getSchema())) { 15664 tableElement.setSchema(tableModel.getSchema()); 15665 } 15666 } 15667 tableElement.setServer(tableModel.getServer()); 15668 if (ambiguousUnqualified) { 15669 tableElement.setName(DlineageUtil.getSimpleTableName(tableModel.getName())); 15670 tableElement.setCandidateTables(new ArrayList<String>(tableModel.getCandidateTables())); 15671 } else { 15672 tableElement.setName(tableModel.getName()); 15673 } 15674 tableElement.setDisplayName(tableModel.getDisplayName()); 15675 tableElement.setStarStmt(tableModel.getStarStmt()); 15676 if(tableModel.isFromDDL()) { 15677 tableElement.setFromDDL(String.valueOf(tableModel.isFromDDL())); 15678 } 15679 15680 // Authoritative endpoint classification (additive). Emit only non-default 15681 // values so existing XML stays byte-identical for unclassified endpoints. 15682 // See docs/tmp/dlineage-authoritative-endpoint-classification.md. 15683 appendEndpointClassification(tableElement, tableModel); 15684 15685 if (tableModel.isPseudo()) { 15686 tableElement.setType("pseudoTable"); 15687 } else { 15688 tableElement.setType("table"); 15689 } 15690 15691 if (tableModel.getSubType() != null) { 15692 if (tableModel.getSubType() == SubType.unnest) { 15693 tableElement.setType(SubType.unnest.name()); 15694 } 15695 else { 15696 tableElement.setSubType(tableModel.getSubType().name()); 15697 } 15698 } 15699 if (tableModel.getParent() != null) { 15700 tableElement.setParent(tableModel.getParent()); 15701 } 15702 if (tableModel.getAlias() != null && tableModel.getAlias().trim().length() > 0) { 15703 tableElement.setAlias(tableModel.getAlias()); 15704 } 15705 if (tableModel.getStartPosition() != null && tableModel.getEndPosition() != null) { 15706 if(option.isTraceTablePosition()){ 15707 for (Pair<Pair3<Long, Long, String>, Pair3<Long, Long, String>> position:tableModel.getPositions()){ 15708 tableElement.appendCoordinate(convertCoordinate(position.first)+","+convertCoordinate(position.second)); 15709 } 15710 } 15711 else { 15712 tableElement.setCoordinate(convertCoordinate(tableModel.getStartPosition()) + "," 15713 + convertCoordinate(tableModel.getEndPosition())); 15714 } 15715 } 15716 if (tableModel.getProcesses() != null) { 15717 List<String> processIds = new ArrayList<String>(); 15718 for (Process process : tableModel.getProcesses()) { 15719 processIds.add(String.valueOf(process.getId())); 15720 } 15721 tableElement.setProcessIds(processIds); 15722 } 15723 15724 table oldTableElement = null; 15725 String tableFullName = DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getQualifiedTableName(tableElement)); 15726 15727 if(tableMap.containsKey(tableFullName)) { 15728 oldTableElement = tableMap.get(tableFullName); 15729 } 15730 else { 15731 tableMap.put(tableFullName, tableElement); 15732 } 15733 15734 if (tableModel.getSubType() == SubType.unnest) { 15735 dataflow.getResultsets().add(tableElement); 15736 } else { 15737 dataflow.getTables().add(tableElement); 15738 } 15739 15740 List<TableColumn> columns = tableModel.getColumns(); 15741 15742 if (containStarColumn(columns)) { 15743 for (TableColumn column : columns) { 15744 if (column.getName().endsWith("*")) { 15745 for (TableColumn starElement : columns) { 15746 if (starElement == column) { 15747 continue; 15748 } 15749 if (starElement.isNotBindStarLinkColumn()) { 15750 continue; 15751 } 15752 TObjectName columnObject = starElement.getColumnObject(); 15753 column.bindStarLinkColumn(columnObject); 15754 } 15755 if (tableModel.isCreateTable() && column.isExpandStar()) { 15756 column.setShowStar(false); 15757 } 15758 } 15759 } 15760 } 15761 15762 for (int j = 0; j < columns.size(); j++) { 15763 TableColumn columnModel = columns.get(j); 15764 15765 if(oldTableElement != null){ 15766 if(!CollectionUtil.isEmpty(oldTableElement.getColumns())){ 15767 for(column oldColumnElement: oldTableElement.getColumns()){ 15768 if(oldColumnElement.getName().equalsIgnoreCase(columnModel.getName())){ 15769 if(columnModel.getDataType() == null && oldColumnElement.getDataType() != null){ 15770 columnModel.setDataType(oldColumnElement.getDataType()); 15771 } 15772 if(columnModel.getPrimaryKey() == null && oldColumnElement.isPrimaryKey() != null){ 15773 columnModel.setPrimaryKey(oldColumnElement.isPrimaryKey()); 15774 } 15775 if(columnModel.getIndexKey() == null && oldColumnElement.isIndexKey() != null){ 15776 columnModel.setIndexKey(oldColumnElement.isIndexKey()); 15777 } 15778 if(columnModel.getUnqiueKey() == null && oldColumnElement.isUnqiueKey() != null){ 15779 columnModel.setUnqiueKey(oldColumnElement.isUnqiueKey()); 15780 } 15781 if(columnModel.getForeignKey() == null && oldColumnElement.isForeignKey() != null){ 15782 columnModel.setForeignKey(oldColumnElement.isForeignKey()); 15783 } 15784 15785 if(oldColumnElement.getDataType() == null && columnModel.getDataType() != null){ 15786 oldColumnElement.setDataType(columnModel.getDataType()); 15787 } 15788 if(oldColumnElement.isPrimaryKey() == null && columnModel.getPrimaryKey() != null){ 15789 oldColumnElement.setPrimaryKey(columnModel.getPrimaryKey()); 15790 } 15791 if(oldColumnElement.isIndexKey() == null && columnModel.getIndexKey() != null){ 15792 oldColumnElement.setIndexKey(columnModel.getIndexKey()); 15793 } 15794 if(oldColumnElement.isUnqiueKey() == null && columnModel.getUnqiueKey() != null){ 15795 oldColumnElement.setUnqiueKey(columnModel.getUnqiueKey()); 15796 } 15797 if(oldColumnElement.isForeignKey() == null && columnModel.getForeignKey() != null){ 15798 oldColumnElement.setForeignKey(columnModel.getForeignKey()); 15799 } 15800 break; 15801 } 15802 } 15803 } 15804 15805 } 15806 15807 if (!columnModel.isPseduo() && columnModel.hasStarLinkColumn() && !columnModel.isVariant()) { 15808 List<String> starLinkColumnList = columnModel.getStarLinkColumnNames(); 15809 for (int k = 0; k < starLinkColumnList.size(); k++) { 15810 column columnElement = new column(); 15811 columnElement.setId(String.valueOf(columnModel.getId()) + "_" + k); 15812 String columnName = starLinkColumnList.get(k); 15813 if (containStarColumn(columns, columnName)) { 15814 continue; 15815 } 15816 columnElement.setName(columnName); 15817 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 15818 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 15819 + convertCoordinate(columnModel.getEndPosition())); 15820 } 15821 if (columnModel.getForeignKey()) { 15822 columnElement.setForeignKey(columnModel.getForeignKey()); 15823 } 15824 if (columnModel.getIndexKey()) { 15825 columnElement.setIndexKey(columnModel.getIndexKey()); 15826 } 15827 if (columnModel.getPrimaryKey()) { 15828 columnElement.setPrimaryKey(columnModel.getPrimaryKey()); 15829 } 15830 if (columnModel.getUnqiueKey()) { 15831 columnElement.setUnqiueKey(columnModel.getUnqiueKey()); 15832 } 15833 if (columnModel.getDataType() != null) { 15834 columnElement.setDataType(columnModel.getDataType()); 15835 } 15836 tableElement.getColumns().add(columnElement); 15837 } 15838 if (columnModel.isShowStar()) { 15839 column columnElement = new column(); 15840 columnElement.setId(String.valueOf(columnModel.getId())); 15841 columnElement.setName(columnModel.getName()); 15842 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 15843 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 15844 + convertCoordinate(columnModel.getEndPosition())); 15845 } 15846 if (columnModel.getForeignKey()) { 15847 columnElement.setForeignKey(columnModel.getForeignKey()); 15848 } 15849 if (columnModel.getIndexKey()) { 15850 columnElement.setIndexKey(columnModel.getIndexKey()); 15851 } 15852 if (columnModel.getPrimaryKey()) { 15853 columnElement.setPrimaryKey(columnModel.getPrimaryKey()); 15854 } 15855 if (columnModel.getUnqiueKey()) { 15856 columnElement.setUnqiueKey(columnModel.getUnqiueKey()); 15857 } 15858 if (columnModel.getDataType() != null) { 15859 columnElement.setDataType(columnModel.getDataType()); 15860 } 15861 tableElement.getColumns().add(columnElement); 15862 } 15863 } else { 15864 column columnElement = new column(); 15865 columnElement.setId(String.valueOf(columnModel.getId())); 15866 columnElement.setName(columnModel.getName()); 15867 columnElement.setDisplayName(columnModel.getDisplayName()); 15868 if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) { 15869 columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + "," 15870 + convertCoordinate(columnModel.getEndPosition())); 15871 } 15872 if (columnModel.isPseduo()) { 15873 columnElement.setSource("system"); 15874 } 15875 if (columnModel.getForeignKey()) { 15876 columnElement.setForeignKey(columnModel.getForeignKey()); 15877 } 15878 if (columnModel.getIndexKey()) { 15879 columnElement.setIndexKey(columnModel.getIndexKey()); 15880 } 15881 if (columnModel.getPrimaryKey()) { 15882 columnElement.setPrimaryKey(columnModel.getPrimaryKey()); 15883 } 15884 if (columnModel.getUnqiueKey()) { 15885 columnElement.setUnqiueKey(columnModel.getUnqiueKey()); 15886 } 15887 if (columnModel.getDataType() != null) { 15888 columnElement.setDataType(columnModel.getDataType()); 15889 } 15890 tableElement.getColumns().add(columnElement); 15891 } 15892 } 15893 15894 TableRelationRows relationRows = tableModel.getRelationRows(); 15895 if (relationRows.hasRelation()) { 15896 column relationRowsElement = new column(); 15897 relationRowsElement.setId(String.valueOf(relationRows.getId())); 15898 relationRowsElement.setName(relationRows.getName()); 15899 if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) { 15900 relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + "," 15901 + convertCoordinate(relationRows.getEndPosition())); 15902 } 15903 relationRowsElement.setSource("system"); 15904 tableElement.getColumns().add(relationRowsElement); 15905 } 15906 } 15907 15908 private boolean containStarColumn(List<TableColumn> columns, String qualifiedColumnName) { 15909 for (TableColumn tableColumn : columns) { 15910 if (DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()).equals(qualifiedColumnName)) { 15911 return true; 15912 } 15913 } 15914 return false; 15915 } 15916 15917 private TableColumn searchTableColumn(List<TableColumn> columns, String qualifiedColumnName) { 15918 for (TableColumn tableColumn : columns) { 15919 if (DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()).equals(qualifiedColumnName)) { 15920 return tableColumn; 15921 } 15922 } 15923 return null; 15924 } 15925 15926 private boolean containStarColumn(Collection<RelationshipElement<?>> elements, String qualifiedColumnName) { 15927 for (RelationshipElement element : elements) { 15928 if (element.getElement() instanceof TableColumn) { 15929 if (DlineageUtil.getIdentifierNormalColumnName(((TableColumn) element.getElement()).getName()) 15930 .equals(qualifiedColumnName)) { 15931 return true; 15932 } 15933 } else if (element.getElement() instanceof ResultColumn) { 15934 if (DlineageUtil.getIdentifierNormalColumnName(((ResultColumn) element.getElement()).getName()) 15935 .equals(qualifiedColumnName)) { 15936 return true; 15937 } 15938 } 15939 } 15940 return false; 15941 } 15942 15943 /** 15944 * Returns true if there is a non-star source element matching the column name 15945 * whose parent (table/resultset) does NOT also contribute a star source in 15946 * the same relationship. This identifies "definitive" explicit sources like 15947 * subquery columns (e.g., "coalesce(...) as col_a") vs incidental references 15948 * (e.g., "aTab.id" where aTab.* is also a source). 15949 */ 15950 private boolean hasDefinitiveNonStarSource(Collection<RelationshipElement<?>> elements, String qualifiedColumnName) { 15951 // First, collect parent IDs of all star (*) sources 15952 Set<Long> starSourceParentIds = new HashSet<Long>(); 15953 for (RelationshipElement<?> element : elements) { 15954 if (element.getElement() instanceof TableColumn) { 15955 TableColumn tc = (TableColumn) element.getElement(); 15956 if ("*".equals(tc.getName()) && tc.getTable() != null) { 15957 starSourceParentIds.add(tc.getTable().getId()); 15958 } 15959 } else if (element.getElement() instanceof ResultColumn) { 15960 ResultColumn rc = (ResultColumn) element.getElement(); 15961 if ("*".equals(rc.getName()) && rc.getResultSet() != null) { 15962 starSourceParentIds.add(rc.getResultSet().getId()); 15963 } 15964 } 15965 } 15966 15967 // Then check if any non-star source matching the column name has a parent 15968 // that does NOT also have a star source 15969 for (RelationshipElement<?> element : elements) { 15970 if (element.getElement() instanceof TableColumn) { 15971 TableColumn tc = (TableColumn) element.getElement(); 15972 if (!"*".equals(tc.getName()) 15973 && DlineageUtil.getIdentifierNormalColumnName(tc.getName()).equals(qualifiedColumnName)) { 15974 if (tc.getTable() != null && !starSourceParentIds.contains(tc.getTable().getId())) { 15975 return true; 15976 } 15977 } 15978 } else if (element.getElement() instanceof ResultColumn) { 15979 ResultColumn rc = (ResultColumn) element.getElement(); 15980 if (!"*".equals(rc.getName()) 15981 && DlineageUtil.getIdentifierNormalColumnName(rc.getName()).equals(qualifiedColumnName)) { 15982 if (rc.getResultSet() != null && !starSourceParentIds.contains(rc.getResultSet().getId())) { 15983 return true; 15984 } 15985 } 15986 } 15987 } 15988 return false; 15989 } 15990 15991 private void analyzeSelectStmt(TSelectSqlStatement stmt) { 15992 if (!accessedSubqueries.contains(stmt)) { 15993 accessedSubqueries.add(stmt); 15994 } else { 15995 if (modelManager.getModel(stmt) != null) { 15996 return; 15997 } 15998 } 15999 16000 if (stmt.getParentStmt() == null && stmt.getIntoClause() == null && stmt.getIntoTableClause() == null) { 16001 if(option.isIgnoreTopSelect() && (option.isIgnoreRecordSet() || option.isSimpleOutput())){ 16002 if(option.getAnalyzeMode() == null || option.getAnalyzeMode() == AnalyzeMode.dataflow){ 16003 return; 16004 } 16005 } 16006 } 16007 16008 if (stmt.getSetOperatorType() != ESetOperatorType.none) { 16009 16010 // Iteratively analyze all descendant UNION branches before processing this node. 16011 // Uses iterative post-order traversal to preserve the original left-right-self 16012 // processing order, avoiding StackOverflow with deeply nested UNION trees. 16013 { 16014 Deque<TSelectSqlStatement> stack1 = new ArrayDeque<>(); 16015 List<TSelectSqlStatement> postOrder = new ArrayList<>(); 16016 stack1.push(stmt); 16017 while (!stack1.isEmpty()) { 16018 TSelectSqlStatement node = stack1.pop(); 16019 postOrder.add(node); 16020 if (node.getSetOperatorType() != ESetOperatorType.none) { 16021 // Push left first, then right, so that after reversal left comes first 16022 if (node.getLeftStmt() != null) stack1.push(node.getLeftStmt()); 16023 if (node.getRightStmt() != null) stack1.push(node.getRightStmt()); 16024 } 16025 } 16026 Collections.reverse(postOrder); 16027 // Process all descendants in post-order, skip stmt itself (processed below) 16028 for (int pi = 0; pi < postOrder.size() - 1; pi++) { 16029 TSelectSqlStatement node = postOrder.get(pi); 16030 if (!accessedStatements.contains(node)) { 16031 accessedStatements.add(node); 16032 analyzeSelectStmt(node); 16033 } 16034 } 16035 } 16036 16037 stmtStack.push(stmt); 16038 SelectSetResultSet resultSet = modelFactory.createSelectSetResultSet(stmt); 16039 16040 ResultSet leftResultSetModel = (ResultSet) modelManager.getModel(stmt.getLeftStmt()); 16041 if (leftResultSetModel != null && leftResultSetModel != resultSet 16042 && !leftResultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 16043 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 16044 impactRelation.setEffectType(EffectType.select); 16045 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 16046 leftResultSetModel.getRelationRows())); 16047 impactRelation.setTarget( 16048 new RelationRowsRelationshipElement<ResultSetRelationRows>(resultSet.getRelationRows())); 16049 } 16050 16051 ResultSet rightResultSetModel = (ResultSet) modelManager.getModel(stmt.getRightStmt()); 16052 if (rightResultSetModel != null && rightResultSetModel != resultSet 16053 && !rightResultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 16054 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 16055 impactRelation.setEffectType(EffectType.select); 16056 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 16057 rightResultSetModel.getRelationRows())); 16058 impactRelation.setTarget( 16059 new RelationRowsRelationshipElement<ResultSetRelationRows>(resultSet.getRelationRows())); 16060 } 16061 16062 if ((leftResultSetModel != null && leftResultSetModel.isDetermined()) 16063 || (rightResultSetModel != null && rightResultSetModel.isDetermined())) { 16064 resultSet.setDetermined(true); 16065 } 16066 16067 if (resultSet.getColumns() == null || resultSet.getColumns().isEmpty()) { 16068 if (getResultColumnList(stmt.getLeftStmt()) != null) { 16069 createSelectSetResultColumns(resultSet, stmt.getLeftStmt()); 16070 } else if (getResultColumnList(stmt.getRightStmt()) != null) { 16071 createSelectSetResultColumns(resultSet, stmt.getRightStmt()); 16072 } 16073 } 16074 16075 List<ResultColumn> columns = resultSet.getColumns(); 16076 for (int i = 0; i < columns.size(); i++) { 16077 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 16078 relation.setEffectType(EffectType.select); 16079 relation.setTarget(new ResultColumnRelationshipElement(columns.get(i))); 16080 16081 if (!stmt.getLeftStmt().isCombinedQuery()) { 16082 ResultSet sourceResultSet = (ResultSet) modelManager 16083 .getModel(stmt.getLeftStmt().getResultColumnList()); 16084 if (sourceResultSet!=null && sourceResultSet.getColumns().size() > i) { 16085 if (columns.get(i).getName().endsWith("*")) { 16086 for (ResultColumn column : sourceResultSet.getColumns()) { 16087 relation.addSource(new ResultColumnRelationshipElement(column)); 16088 } 16089 } else { 16090 relation.addSource( 16091 new ResultColumnRelationshipElement(sourceResultSet.getColumns().get(i))); 16092 } 16093 } 16094 } else { 16095 ResultSet sourceResultSet = (ResultSet) modelManager.getModel(stmt.getLeftStmt()); 16096 if (sourceResultSet != null && sourceResultSet.getColumns().size() > i) { 16097 if (columns.get(i).getName().endsWith("*")) { 16098 for (ResultColumn column : sourceResultSet.getColumns()) { 16099 relation.addSource(new ResultColumnRelationshipElement(column)); 16100 } 16101 } else { 16102 relation.addSource( 16103 new ResultColumnRelationshipElement(sourceResultSet.getColumns().get(i))); 16104 } 16105 } 16106 } 16107 16108 if (!stmt.getRightStmt().isCombinedQuery()) { 16109 ResultSet sourceResultSet = (ResultSet) modelManager 16110 .getModel(stmt.getRightStmt().getResultColumnList()); 16111 if (sourceResultSet != null && sourceResultSet.getColumns().size() > i) { 16112 if (columns.get(i).getName().endsWith("*")) { 16113 for (ResultColumn column : sourceResultSet.getColumns()) { 16114 relation.addSource(new ResultColumnRelationshipElement(column)); 16115 } 16116 } else { 16117 relation.addSource( 16118 new ResultColumnRelationshipElement(sourceResultSet.getColumns().get(i))); 16119 } 16120 } else if (sourceResultSet != null) { 16121 for (ResultColumn column : sourceResultSet.getColumns()) { 16122 if (column.hasStarLinkColumn()) { 16123 relation.addSource(new ResultColumnRelationshipElement(column)); 16124 } 16125 } 16126 } 16127 } else { 16128 ResultSet sourceResultSet = (ResultSet) modelManager.getModel(stmt.getRightStmt()); 16129 if (sourceResultSet != null && sourceResultSet.getColumns().size() > i) { 16130 relation.addSource(new ResultColumnRelationshipElement(sourceResultSet.getColumns().get(i))); 16131 } else if (sourceResultSet != null) { 16132 for (ResultColumn column : sourceResultSet.getColumns()) { 16133 if (column.hasStarLinkColumn()) { 16134 relation.addSource(new ResultColumnRelationshipElement(column)); 16135 } 16136 } 16137 } 16138 } 16139 } 16140 16141 analyzeSelectIntoClause(stmt); 16142 16143 stmtStack.pop(); 16144 } else { 16145 16146 // handle hive stmt, issue_id I3SGZB 16147 if (stmt.getHiveBodyList() != null && stmt.getHiveBodyList().size() > 0) { 16148 stmtStack.push(stmt); 16149 hiveFromTables = stmt.tables; 16150 if (hiveFromTables != null) { 16151 for (int i = 0; i < hiveFromTables.size(); i++) { 16152 modelFactory.createTable(hiveFromTables.getTable(i)); 16153 } 16154 } 16155 for (int i = 0; i < stmt.getHiveBodyList().size(); i++) { 16156 analyzeCustomSqlStmt(stmt.getHiveBodyList().get(i)); 16157 } 16158 stmtStack.pop(); 16159 return; 16160 } 16161 16162 if (stmt.getTransformClause() != null) { 16163 analyzeHiveTransformClause(stmt, stmt.getTransformClause()); 16164 return; 16165 } 16166 16167 if (stmt.getResultColumnList() == null) { 16168 return; 16169 } 16170 16171 stmtStack.push(stmt); 16172 16173 TTableList fromTables = stmt.tables; 16174 if ((fromTables == null || fromTables.size() == 0) 16175 && (hiveFromTables != null && hiveFromTables.size() > 0)) { 16176 fromTables = hiveFromTables; 16177 } 16178 16179 for (int i = 0; i < fromTables.size(); i++) { 16180 TTable table = fromTables.getTable(i); 16181 if (table.getLateralViewList() != null && !table.getLateralViewList().isEmpty()) { 16182 analyzeTableSubquery(table); 16183 analyzeLateralView(stmt, table, table.getLateralViewList()); 16184 stmtStack.pop(); 16185 return; 16186 } 16187 if (table.getUnnestClause() != null && option.getVendor() == EDbVendor.dbvpresto) { 16188 analyzeTableSubquery(table); 16189 analyzePrestoUnnest(stmt, table); 16190 stmtStack.pop(); 16191 return; 16192 } 16193 if (table.getUnnestClause() != null && option.getVendor() == EDbVendor.dbvbigquery) { 16194 analyzeBigQueryUnnest(stmt, table); 16195 } 16196 } 16197 16198 //用来获取 pivotedTable 对应的columns 16199 TPivotedTable pivotedTable = null; 16200 if (stmt.getJoins() != null && stmt.getJoins().size() > 0) { 16201 for (TJoin join : stmt.getJoins()) { 16202 if (join.getTable() != null && join.getTable().getPivotedTable() != null) { 16203 if (isUnPivotedTable(join.getTable().getPivotedTable())) { 16204 analyzeUnPivotedTable(stmt, join.getTable().getPivotedTable()); 16205 pivotedTable = join.getTable().getPivotedTable(); 16206 } else { 16207 analyzePivotedTable(stmt, join.getTable().getPivotedTable()); 16208 pivotedTable = join.getTable().getPivotedTable(); 16209 } 16210 } 16211 } 16212 } 16213 16214 for (int i = 0; i < fromTables.size(); i++) { 16215 TTable table = fromTables.getTable(i); 16216 // Handle TABLE(func()) which has tableType=tableExpr and funcCall=null 16217 if (table.getTableType() == ETableSource.tableExpr && table.getFuncCall() == null && pipelinedAnalyzer != null) { 16218 try { 16219 pipelinedAnalyzer.tryStitchTableExpr(table); 16220 } catch (Exception e) { 16221 // Don't let pipelined stitching failure break main flow 16222 } 16223 } 16224 16225 if (table.getFuncCall() != null || (table.getTableExpr()!=null && table.getTableExpr().getFunctionCall()!=null)) { 16226 TFunctionCall functionCall = table.getFuncCall(); 16227 if (functionCall == null) { 16228 functionCall = table.getTableExpr().getFunctionCall(); 16229 } 16230 Procedure callee = modelManager.getProcedureByName( 16231 DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 16232 if (callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) { 16233 analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 16234 callee = modelManager.getProcedureByName( 16235 DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall))); 16236 } 16237 16238 if(callee!=null) { 16239 if (callee.getArguments() != null) { 16240 for (int j = 0; j < callee.getArguments().size(); j++) { 16241 Argument argument = callee.getArguments().get(j); 16242 Variable variable = modelFactory.createVariable(callee, argument.getName(), false); 16243 if(variable!=null) { 16244 if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) { 16245 Transform transform = new Transform(); 16246 transform.setType(Transform.FUNCTION); 16247 transform.setCode(functionCall); 16248 variable.getColumns().get(0).setTransform(transform); 16249 } 16250 Process process = modelFactory.createProcess(functionCall); 16251 variable.addProcess(process); 16252 analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, j, process); 16253 } 16254 } 16255 } 16256 Set<Object> functionTableModelObjs = modelManager.getFunctionTable(DlineageUtil 16257 .getIdentifierNormalTableName(functionCall.getFunctionName().toString())); 16258 if (functionTableModelObjs != null) { 16259 modelManager.bindModel(table, functionTableModelObjs.iterator().next()); 16260 } 16261 // Try pipelined function stitching 16262 if (pipelinedAnalyzer != null) { 16263 try { 16264 pipelinedAnalyzer.tryStitchCallSite(table, functionCall); 16265 } catch (Exception e) { 16266 // Don't let pipelined stitching failure break main flow 16267 } 16268 } 16269 continue; 16270 } else { 16271 Set<Object> functionTableModelObjs = modelManager.getFunctionTable(DlineageUtil 16272 .getIdentifierNormalTableName(functionCall.getFunctionName().toString())); 16273 if (functionTableModelObjs == null) { 16274// Procedure procedure = modelManager.getProcedureByName(DlineageUtil 16275// .getIdentifierNormalTableName(functionCall.getFunctionName().toString())); 16276// if (procedure != null) { 16277 createFunction(functionCall); 16278 continue; 16279// } 16280 } 16281 if (functionTableModelObjs!=null && functionTableModelObjs.iterator().next() instanceof Table) { 16282 Table functionTableModel = (Table) functionTableModelObjs.iterator().next(); 16283 if (functionTableModel.getColumns() != null) { 16284 Table functionTable = modelFactory.createTableFromCreateDDL(table, true); 16285 if (functionTable == functionTableModel) 16286 continue; 16287 for (int j = 0; j < functionTableModel.getColumns().size(); j++) { 16288 TableColumn column = modelFactory.createTableColumn(functionTable, 16289 functionTableModel.getColumns().get(j).getColumnObject(), true); 16290 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 16291 relation.setEffectType(EffectType.select); 16292 relation.setTarget(new TableColumnRelationshipElement(column)); 16293 relation.addSource( 16294 new TableColumnRelationshipElement(functionTableModel.getColumns().get(j))); 16295 } 16296 } 16297 } else if (functionTableModelObjs!=null && functionTableModelObjs.iterator().next() instanceof ResultSet) { 16298 ResultSet functionTableModel = (ResultSet) functionTableModelObjs.iterator().next(); 16299 if (functionTableModel.getColumns() != null) { 16300 Table functionTable = modelFactory.createTableFromCreateDDL(table, true); 16301 for (int j = 0; j < functionTableModel.getColumns().size(); j++) { 16302 TParseTreeNode columnObj = functionTableModel.getColumns().get(j).getColumnObject(); 16303 if (columnObj instanceof TObjectName) { 16304 TableColumn column = modelFactory.createTableColumn(functionTable, 16305 (TObjectName) columnObj, true); 16306 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 16307 relation.setEffectType(EffectType.select); 16308 relation.setTarget(new TableColumnRelationshipElement(column)); 16309 relation.addSource(new ResultColumnRelationshipElement( 16310 functionTableModel.getColumns().get(j))); 16311 } else if (columnObj instanceof TResultColumn) { 16312 TableColumn column = modelFactory.createTableColumn(functionTable, 16313 (TResultColumn) columnObj); 16314 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 16315 relation.setEffectType(EffectType.select); 16316 relation.setTarget(new TableColumnRelationshipElement(column)); 16317 relation.addSource(new ResultColumnRelationshipElement( 16318 functionTableModel.getColumns().get(j))); 16319 } 16320 } 16321 } 16322 } 16323 // Try pipelined function stitching for unresolved function calls 16324 if (pipelinedAnalyzer != null) { 16325 try { 16326 pipelinedAnalyzer.tryStitchCallSite(table, functionCall); 16327 } catch (Exception e) { 16328 // Don't let pipelined stitching failure break main flow 16329 } 16330 } 16331 } 16332 } 16333 16334 if (table.getPartitionExtensionClause() != null 16335 && table.getPartitionExtensionClause().getKeyValues() != null) { 16336 TExpressionList values = table.getPartitionExtensionClause().getKeyValues(); 16337 Table tableModel = modelFactory.createTable(table); 16338 for (TExpression value : values) { 16339 if (value.getExpressionType() == EExpressionType.simple_constant_t) { 16340 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 16341 impactRelation.setEffectType(EffectType.select); 16342 Table constantTable = modelFactory.createConstantsTable(stmtStack.peek()); 16343 TableColumn constantColumn = modelFactory.createTableColumn(constantTable, value.getConstantOperand()); 16344 impactRelation.addSource(new TableColumnRelationshipElement(constantColumn)); 16345 impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>( 16346 tableModel.getRelationRows())); 16347 } 16348 } 16349 } 16350 16351 if (table.getSubquery() != null) { 16352 QueryTable queryTable = modelFactory.createQueryTable(table); 16353 TSelectSqlStatement subquery = table.getSubquery(); 16354 analyzeSelectStmt(subquery); 16355 16356 ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery); 16357 if (resultSetModel != null && resultSetModel.isDetermined()) { 16358 queryTable.setDetermined(true); 16359 } 16360 16361 if (resultSetModel != null && resultSetModel != queryTable 16362 && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 16363 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 16364 impactRelation.setEffectType(EffectType.select); 16365 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 16366 resultSetModel.getRelationRows())); 16367 impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 16368 queryTable.getRelationRows())); 16369 } 16370 16371 if (resultSetModel != null && resultSetModel != queryTable 16372 && queryTable.getTableObject().getAliasClause() != null 16373 && queryTable.getTableObject().getAliasClause().getColumns() != null) { 16374 for (int j = 0; j < queryTable.getColumns().size() 16375 && j < resultSetModel.getColumns().size(); j++) { 16376 ResultColumn sourceColumn = resultSetModel.getColumns().get(j); 16377 ResultColumn targetColumn = queryTable.getColumns().get(j); 16378 16379 DataFlowRelationship queryRalation = modelFactory.createDataFlowRelation(); 16380 queryRalation.setEffectType(EffectType.select); 16381 queryRalation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 16382 queryRalation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 16383 } 16384 } else if (subquery.getSetOperatorType() != ESetOperatorType.none) { 16385 SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager 16386 .getModel(subquery); 16387 for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) { 16388 ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j); 16389 ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable, 16390 sourceColumn); 16391 for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) { 16392 targetColumn.bindStarLinkColumn(starLinkColumn); 16393 } 16394 DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation(); 16395 selectSetRalation.setEffectType(EffectType.select); 16396 selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 16397 selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 16398 } 16399 } 16400 } else if (table.getOutputMerge() != null) { 16401 QueryTable queryTable = modelFactory.createQueryTable(table); 16402 TMergeSqlStatement subquery = table.getOutputMerge(); 16403 analyzeMergeStmt(subquery); 16404 16405 for (TResultColumn column : subquery.getOutputClause().getSelectItemList()) { 16406 modelFactory.createResultColumn(queryTable, column); 16407 analyzeResultColumn(column, EffectType.select); 16408 } 16409 16410 ResultSet resultSetModel = (ResultSet) modelManager 16411 .getModel(subquery.getOutputClause().getSelectItemList()); 16412 16413 if (resultSetModel != null && resultSetModel != queryTable 16414 && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 16415 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 16416 impactRelation.setEffectType(EffectType.select); 16417 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 16418 resultSetModel.getRelationRows())); 16419 impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 16420 queryTable.getRelationRows())); 16421 } 16422 16423 if (resultSetModel != null && resultSetModel != queryTable 16424 && queryTable.getTableObject().getAliasClause() != null 16425 && queryTable.getTableObject().getAliasClause().getColumns() != null) { 16426 for (int j = 0; j < queryTable.getColumns().size() 16427 && j < resultSetModel.getColumns().size(); j++) { 16428 ResultColumn sourceColumn = resultSetModel.getColumns().get(j); 16429 ResultColumn targetColumn = queryTable.getColumns().get(j); 16430 16431 DataFlowRelationship queryRalation = modelFactory.createDataFlowRelation(); 16432 queryRalation.setEffectType(EffectType.select); 16433 queryRalation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 16434 queryRalation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 16435 } 16436 } 16437 } else if (table.getTableExpr() != null && table.getTableExpr().getSubQuery() != null) { 16438 QueryTable queryTable = modelFactory.createQueryTable(table); 16439 TSelectSqlStatement subquery = table.getTableExpr().getSubQuery(); 16440 analyzeSelectStmt(subquery); 16441 16442 ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery); 16443 16444 if (resultSetModel != null && resultSetModel != queryTable 16445 && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 16446 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 16447 impactRelation.setEffectType(EffectType.select); 16448 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 16449 resultSetModel.getRelationRows())); 16450 impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 16451 queryTable.getRelationRows())); 16452 } 16453 16454 if (resultSetModel != null && resultSetModel != queryTable 16455 && queryTable.getTableObject().getAliasClause() != null) { 16456 for (int j = 0; j < resultSetModel.getColumns().size(); j++) { 16457 ResultColumn sourceColumn = resultSetModel.getColumns().get(j); 16458 ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable, 16459 sourceColumn); 16460 16461 DataFlowRelationship queryRalation = modelFactory.createDataFlowRelation(); 16462 queryRalation.setEffectType(EffectType.select); 16463 queryRalation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 16464 queryRalation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 16465 } 16466 } else if (subquery.getSetOperatorType() != ESetOperatorType.none) { 16467 SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager 16468 .getModel(subquery); 16469 for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) { 16470 ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j); 16471 ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable, 16472 sourceColumn); 16473 for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) { 16474 targetColumn.bindStarLinkColumn(starLinkColumn); 16475 } 16476 DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation(); 16477 selectSetRalation.setEffectType(EffectType.select); 16478 selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 16479 selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 16480 } 16481 } 16482 } else if (table.getCTE() != null) { 16483 QueryTable queryTable = modelFactory.createQueryTable(table); 16484 16485 TObjectNameList cteColumns = table.getCTE().getColumnList(); 16486 if (cteColumns != null) { 16487 for (int j = 0; j < cteColumns.size(); j++) { 16488 modelFactory.createResultColumn(queryTable, cteColumns.getObjectName(j)); 16489 } 16490 queryTable.setDetermined(true); 16491 } 16492 TSelectSqlStatement subquery = table.getCTE().getSubquery(); 16493 if (subquery != null && !stmtStack.contains(subquery) && subquery.getResultColumnList() != null) { 16494 analyzeSelectStmt(subquery); 16495 16496 ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery); 16497 if (resultSetModel != null && resultSetModel != queryTable 16498 && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 16499 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 16500 impactRelation.setEffectType(EffectType.select); 16501 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 16502 resultSetModel.getRelationRows())); 16503 impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 16504 queryTable.getRelationRows())); 16505 } 16506 16507 if (subquery.getSetOperatorType() != ESetOperatorType.none) { 16508 SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager 16509 .getModel(subquery); 16510 int x = 0; 16511 for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) { 16512 ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j); 16513 ResultColumn targetColumn = null; 16514 if (cteColumns != null) { 16515 if (queryTable.getColumns().size() <= j) { 16516 for (int k = 0; k < queryTable.getColumns().size(); k++) { 16517 if (queryTable.getColumns().get(k).getName().equals(sourceColumn.getName()) 16518 || queryTable.getColumns().get(k).getName() 16519 .equals(sourceColumn.getAlias())) { 16520 targetColumn = queryTable.getColumns().get(k); 16521 } 16522 } 16523 } else { 16524 if (x < j) { 16525 x = j; 16526 } 16527 targetColumn = queryTable.getColumns().get(x); 16528 x++; 16529 if (resultSetModel.getColumns().get(j).getName().contains("*") 16530 && x < cteColumns.size()) { 16531 j--; 16532 } 16533 } 16534 } else { 16535 targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn); 16536 } 16537 for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) { 16538 targetColumn.bindStarLinkColumn(starLinkColumn); 16539 } 16540 DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation(); 16541 selectSetRalation.setEffectType(EffectType.select); 16542 selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 16543 selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 16544 } 16545 if (!queryTable.isDetermined()) { 16546 queryTable.setDetermined(selectSetResultSetModel.isDetermined()); 16547 } 16548 } else { 16549 int x = 0; 16550 for (int j = 0; j < resultSetModel.getColumns().size(); j++) { 16551 ResultColumn sourceColumn = resultSetModel.getColumns().get(j); 16552 ResultColumn targetColumn = null; 16553 if (cteColumns != null) { 16554 if (queryTable.getColumns().size() <= j) { 16555 for (int k = 0; k < queryTable.getColumns().size(); k++) { 16556 if (queryTable.getColumns().get(k).getName().equals(sourceColumn.getName()) 16557 || queryTable.getColumns().get(k).getName() 16558 .equals(sourceColumn.getAlias())) { 16559 targetColumn = queryTable.getColumns().get(k); 16560 } 16561 } 16562 } else { 16563 if (x < j) { 16564 x = j; 16565 } 16566 targetColumn = queryTable.getColumns().get(x); 16567 x++; 16568 if (resultSetModel.getColumns().get(j).getName().contains("*") 16569 && x < cteColumns.size()) { 16570 j--; 16571 } 16572 } 16573 } else { 16574 targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn); 16575 } 16576 for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) { 16577 targetColumn.bindStarLinkColumn(starLinkColumn); 16578 } 16579 DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation(); 16580 selectSetRalation.setEffectType(EffectType.select); 16581 selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 16582 selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 16583 } 16584 if (!queryTable.isDetermined()) { 16585 queryTable.setDetermined(resultSetModel.isDetermined()); 16586 } 16587 } 16588 } else if (table.getCTE().getUpdateStmt() != null) { 16589 analyzeCustomSqlStmt(table.getCTE().getUpdateStmt()); 16590 } else if (table.getCTE().getInsertStmt() != null) { 16591 analyzeCustomSqlStmt(table.getCTE().getInsertStmt()); 16592 } else if (table.getCTE().getDeleteStmt() != null) { 16593 analyzeCustomSqlStmt(table.getCTE().getDeleteStmt()); 16594 } 16595 } else if (table.getTableType().name().startsWith("open")) { 16596 continue; 16597 } else if (table.getTableType() == ETableSource.jsonTable) { 16598 Table functionTable = modelFactory.createJsonTable(table); 16599 TJsonTable jsonTable = table.getJsonTable(); 16600 TColumnDefinitionList definitions = jsonTable.getColumnDefinitions(); 16601 if (definitions != null) { 16602 for (int j = 0; j < definitions.size(); j++) { 16603 TColumnDefinitionList nestDefinitions = definitions.getColumn(j).getNestedTableColumns(); 16604 if(nestDefinitions!=null) { 16605 for(int k=0;k<nestDefinitions.size();k++){ 16606 TableColumn column = modelFactory.createTableColumn(functionTable, 16607 nestDefinitions.getColumn(k).getColumnName(), true); 16608 if (nestDefinitions.getColumn(k).getColumnPath() != null) { 16609 column.setDisplayName( 16610 column.getName() + ":" + nestDefinitions.getColumn(k).getColumnPath()); 16611 } 16612 } 16613 } 16614 else { 16615 TableColumn column = modelFactory.createTableColumn(functionTable, 16616 definitions.getColumn(j).getColumnName(), true); 16617 if (definitions.getColumn(j).getColumnPath() != null) { 16618 column.setDisplayName( 16619 column.getName() + ":" + definitions.getColumn(j).getColumnPath()); 16620 } 16621 } 16622 } 16623 } else { 16624 TObjectName keyColumn = new TObjectName(); 16625 keyColumn.setString("key"); 16626 modelFactory.createJsonTableColumn(functionTable, keyColumn); 16627 TObjectName valueColumn = new TObjectName(); 16628 valueColumn.setString("value"); 16629 modelFactory.createJsonTableColumn(functionTable, valueColumn); 16630 TObjectName typeColumn = new TObjectName(); 16631 typeColumn.setString("type"); 16632 modelFactory.createJsonTableColumn(functionTable, typeColumn); 16633 } 16634 16635 functionTable.setCreateTable(true); 16636 functionTable.setSubType(SubType.function); 16637 modelManager.bindCreateModel(table, functionTable); 16638 16639 if (jsonTable.getJsonExpression() == null) { 16640 ErrorInfo errorInfo = new ErrorInfo(); 16641 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 16642 errorInfo.setErrorMessage("Can't handle the json table: " + jsonTable.toString()); 16643 errorInfo.setStartPosition(new Pair3<Long, Long, String>(jsonTable.getStartToken().lineNo, 16644 jsonTable.getStartToken().columnNo, ModelBindingManager.getGlobalHash())); 16645 errorInfo.setEndPosition(new Pair3<Long, Long, String>(jsonTable.getEndToken().lineNo, 16646 jsonTable.getEndToken().columnNo + jsonTable.getEndToken().getAstext().length(), 16647 ModelBindingManager.getGlobalHash())); 16648 errorInfo.fillInfo(this); 16649 errorInfos.add(errorInfo); 16650 } else { 16651 String jsonName = jsonTable.getJsonExpression().toString(); 16652 if (!jsonName.startsWith("@")) { 16653 columnsInExpr visitor = new columnsInExpr(); 16654 jsonTable.getJsonExpression().inOrderTraverse(visitor); 16655 List<TObjectName> objectNames = visitor.getObjectNames(); 16656 List<TParseTreeNode> functions = visitor.getFunctions(); 16657 List<TParseTreeNode> constants = visitor.getConstants(); 16658 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 16659 16660 for (int j = 0; j < functionTable.getColumns().size(); j++) { 16661 TableColumn tableColumn = functionTable.getColumns().get(j); 16662 if (functions != null && !functions.isEmpty()) { 16663 analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function); 16664 } 16665 if (subquerys != null && !subquerys.isEmpty()) { 16666 analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select); 16667 } 16668 if (objectNames != null && !objectNames.isEmpty()) { 16669 analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions); 16670 } 16671 if (constants != null && !constants.isEmpty()) { 16672 analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, 16673 functions); 16674 } 16675 } 16676 } else { 16677 TStatementList stmts = stmt.getGsqlparser().getSqlstatements(); 16678 for (int j = 0; j < stmts.size(); j++) { 16679 TCustomSqlStatement item = stmts.get(j); 16680 if (item instanceof TMssqlDeclare) { 16681 if (analyzeMssqlJsonDeclare((TMssqlDeclare) item, jsonName, functionTable)) { 16682 break; 16683 } 16684 } 16685 } 16686 } 16687 } 16688 } else if (table.getTableType() == ETableSource.xmltable) { 16689 Table functionTable = modelFactory.createXmlTable(table); 16690 TXmlTable xmlTable = table.getXmlTable(); 16691 TXmlTableParameter param = xmlTable != null ? xmlTable.getArg() : null; 16692 16693 // Output columns from COLUMNS clause 16694 if (param != null && param.getXmlTableColumns() != null) { 16695 TColumnDefinitionList defs = param.getXmlTableColumns(); 16696 for (int j = 0; j < defs.size(); j++) { 16697 TColumnDefinition def = defs.getColumn(j); 16698 TableColumn column = modelFactory.createTableColumn( 16699 functionTable, def.getColumnName(), true); 16700 if (def.getXmlTableColumnPath() != null) { 16701 column.setDisplayName( 16702 column.getName() + ":" + def.getXmlTableColumnPath()); 16703 } 16704 } 16705 } 16706 functionTable.setCreateTable(true); 16707 functionTable.setSubType(SubType.function); 16708 modelManager.bindCreateModel(table, functionTable); 16709 16710 // Source columns from PASSING (v1: many-to-many) 16711 TResultColumnList passing = null; 16712 if (param != null && param.getXmlPassingClause() != null) { 16713 passing = param.getXmlPassingClause().getPassingList(); 16714 } 16715 if (passing != null && passing.size() > 0) { 16716 columnsInExpr visitor = new columnsInExpr(); 16717 for (int p = 0; p < passing.size(); p++) { 16718 TExpression e = passing.getResultColumn(p).getExpr(); 16719 if (e != null) e.inOrderTraverse(visitor); 16720 } 16721 List<TObjectName> objectNames = visitor.getObjectNames(); 16722 List<TParseTreeNode> functions = visitor.getFunctions(); 16723 List<TParseTreeNode> constants = visitor.getConstants(); 16724 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 16725 16726 for (int j = 0; j < functionTable.getColumns().size(); j++) { 16727 TableColumn tc = functionTable.getColumns().get(j); 16728 if (functions != null && !functions.isEmpty()) 16729 analyzeFunctionDataFlowRelation(tc, functions, EffectType.function); 16730 if (subquerys != null && !subquerys.isEmpty()) 16731 analyzeSubqueryDataFlowRelation(tc, subquerys, EffectType.select); 16732 if (objectNames != null && !objectNames.isEmpty()) 16733 analyzeDataFlowRelation(tc, objectNames, EffectType.select, functions); 16734 if (constants != null && !constants.isEmpty()) 16735 analyzeConstantDataFlowRelation(tc, constants, EffectType.select, functions); 16736 } 16737 } else { 16738 ErrorInfo errorInfo = new ErrorInfo(); 16739 errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR); 16740 errorInfo.setErrorMessage("Can't analyze XMLTABLE: missing PASSING clause."); 16741 errorInfos.add(errorInfo); 16742 } 16743 } else if (getTableLinkedColumns(table) != null && getTableLinkedColumns(table).size() > 0) { 16744 if (table.getTableType() == ETableSource.rowList && table.getRowList() != null 16745 && table.getRowList().size() > 0) { 16746 Table tableModel = modelFactory.createTable(table); 16747 for (int j = 0; j < table.getRowList().size(); j++) { 16748 TMultiTarget rowList = table.getRowList().getMultiTarget(j); 16749 for (int k = 0; k < rowList.getColumnList().size(); k++) { 16750 TResultColumn column = rowList.getColumnList().getResultColumn(k); 16751 if (column.getFieldAttr() == null) 16752 continue; 16753 TableColumn tableColumn = modelFactory.createTableColumn(tableModel, 16754 column.getFieldAttr(), true); 16755 16756 columnsInExpr visitor = new columnsInExpr(); 16757 column.getExpr().inOrderTraverse(visitor); 16758 List<TObjectName> objectNames = visitor.getObjectNames(); 16759 List<TParseTreeNode> functions = visitor.getFunctions(); 16760 List<TParseTreeNode> constants = visitor.getConstants(); 16761 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 16762 16763 if (functions != null && !functions.isEmpty()) { 16764 analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function); 16765 } 16766 if (subquerys != null && !subquerys.isEmpty()) { 16767 analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select); 16768 } 16769 if (objectNames != null && !objectNames.isEmpty()) { 16770 analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions); 16771 } 16772 if (constants != null && !constants.isEmpty()) { 16773 analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, 16774 functions); 16775 } 16776 } 16777 } 16778 } else { 16779 if(table.getTableType() == ETableSource.pivoted_table) { 16780 continue; 16781 } 16782 if (table.getTableType() == ETableSource.rowList) { 16783 List<TResultColumnList> rowList = table.getValueClause().getRows(); 16784 16785 QueryTable tableModel = modelFactory.createQueryTable(table); 16786 TAliasClause aliasClause = table.getAliasClause(); 16787 if (aliasClause != null && aliasClause.getColumns() != null) { 16788 for (TObjectName column : aliasClause.getColumns()) { 16789 modelFactory.createResultColumn(tableModel, column, true); 16790 } 16791 } else { 16792 int columnCount = rowList.get(0).size(); 16793 for (int j = 1; j <= columnCount; j++) { 16794 TObjectName columnName = new TObjectName(); 16795 columnName.setString("column" + j); 16796 modelFactory.createResultColumn(tableModel, columnName, true); 16797 } 16798 } 16799 tableModel.setDetermined(true); 16800 16801 for (TResultColumnList resultColumnList : rowList) { 16802 for (int j = 0; j < resultColumnList.size(); j++) { 16803 TResultColumn resultColumn = resultColumnList.getResultColumn(j); 16804 analyzeValueColumn(tableModel.getColumns().get(j), resultColumn, EffectType.select); 16805 } 16806 } 16807 16808 } else { 16809 Table tableModel = modelFactory.createTable(table); 16810 for (int j = 0; j < getTableLinkedColumns(table).size(); j++) { 16811 TObjectName object = getTableLinkedColumns(table).getObjectName(j); 16812 16813 if (object.getDbObjectType() == EDbObjectType.variable) { 16814 continue; 16815 } 16816 16817 if (object.getColumnNameOnly().startsWith("@") 16818 && (option.getVendor() == EDbVendor.dbvmssql 16819 || option.getVendor() == EDbVendor.dbvazuresql)) { 16820 continue; 16821 } 16822 16823 if (object.getColumnNameOnly().startsWith(":") 16824 && (option.getVendor() == EDbVendor.dbvhana 16825 || option.getVendor() == EDbVendor.dbvteradata)) { 16826 continue; 16827 } 16828 16829 if (isBuiltInFunctionName(object) && isFromFunction(object)) { 16830 continue; 16831 } 16832 16833 if (!"*".equals(getColumnName(object))) { 16834 if (isStructColumn(object)) { 16835 16836 } else { 16837 if (pivotedTable != null) { 16838 ResultColumn resultColumn = getPivotedTableColumn(pivotedTable, object); 16839 if (resultColumn != null) { 16840 continue; 16841 } 16842 } 16843 TableColumn tableColumn = modelFactory.createTableColumn(tableModel, object, 16844 false); 16845 if(tableColumn == null) { 16846 continue; 16847 } 16848 if (table.getUnnestClause() != null 16849 && table.getUnnestClause().getArrayExpr() != null) { 16850 columnsInExpr visitor = new columnsInExpr(); 16851 table.getUnnestClause().getArrayExpr().inOrderTraverse(visitor); 16852 16853 List<TObjectName> objectNames = visitor.getObjectNames(); 16854 List<TParseTreeNode> functions = visitor.getFunctions(); 16855 16856 if (functions != null && !functions.isEmpty()) { 16857 analyzeFunctionDataFlowRelation(tableColumn, functions, 16858 EffectType.select); 16859 16860 } 16861 16862 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 16863 if (subquerys != null && !subquerys.isEmpty()) { 16864 analyzeSubqueryDataFlowRelation(tableColumn, subquerys, 16865 EffectType.select); 16866 } 16867 16868 analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, 16869 functions); 16870 16871 List<TParseTreeNode> constants = visitor.getConstants(); 16872 analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, 16873 functions); 16874 } 16875 } 16876 } else { 16877 boolean flag = false; 16878 for (TObjectName column : getTableLinkedColumns(table)) { 16879 if ("*".equals(getColumnName(column))) { 16880 continue; 16881 } 16882 if (column.getLocation() != ESqlClause.where 16883 && column.getLocation() != ESqlClause.joinCondition) { 16884 flag = true; 16885 } 16886 } 16887 if (!flag) { 16888 TableColumn tableColumn = modelFactory.createTableColumn(tableModel, object, 16889 false); 16890 if (tableColumn != null && !tableModel.hasSQLEnv()) { 16891 tableColumn.setShowStar(true); 16892 } 16893 } 16894 } 16895 16896 } 16897 } 16898 } 16899 } 16900 else { 16901 modelFactory.createTable(table); 16902 } 16903 } 16904 16905 if (pivotedTable!=null) { 16906 for (TJoin join : stmt.getJoins()) { 16907 if (join.getTable() != null && join.getTable().getPivotedTable() != null) { 16908 if (isUnPivotedTable(join.getTable().getPivotedTable())) { 16909 analyzeUnPivotedTable(stmt, join.getTable().getPivotedTable()); 16910 } else { 16911 analyzePivotedTable(stmt, join.getTable().getPivotedTable()); 16912 } 16913 stmtStack.pop(); 16914 return; 16915 } 16916 } 16917 } 16918 16919 if (!stmt.isCombinedQuery()) { 16920 Object queryModel = modelManager.getModel(stmt.getResultColumnList()); 16921 16922 if (queryModel == null) { 16923 TSelectSqlStatement parentStmt = getParentSetSelectStmt(stmt); 16924 if (isTopResultSet(stmt) || parentStmt == null) { 16925 ResultSet resultSetModel = modelFactory.createResultSet(stmt, 16926 isTopResultSet(stmt) && isShowTopSelectResultSet() && stmt.getIntoClause() == null); 16927 16928 createPseudoImpactRelation(stmt, resultSetModel, EffectType.select); 16929 16930 boolean isDetermined = true; 16931 Map<String, AtomicInteger> keyMap = new HashMap<String, AtomicInteger>(); 16932 Set<String> columnNames = new HashSet<String>(); 16933 for (int i = 0; i < stmt.getResultColumnList().size(); i++) { 16934 TResultColumn column = stmt.getResultColumnList().getResultColumn(i); 16935 16936 if (column.getExpr().getComparisonType() == EComparisonType.equals 16937 && column.getExpr().getLeftOperand().getObjectOperand() != null) { 16938 TObjectName columnObject = column.getExpr().getLeftOperand().getObjectOperand(); 16939 16940 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, 16941 columnObject); 16942 if (columnObject.getDbObjectType() == EDbObjectType.variable) { 16943 Table variable = modelManager 16944 .getTableByName(DlineageUtil.getTableFullName(columnObject.toString())); 16945 if (variable != null) { 16946 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 16947 relation.setEffectType(EffectType.select); 16948 TableColumn columnModel = variable.getColumns().get(0); 16949 relation.setTarget(new TableColumnRelationshipElement(columnModel)); 16950 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 16951 } else { 16952 variable = modelFactory.createVariable(columnObject); 16953 variable.setCreateTable(true); 16954 variable.setSubType(SubType.record); 16955 TObjectName variableProperties = new TObjectName(); 16956 variableProperties.setString("*"); 16957 TableColumn variableProperty = modelFactory.createTableColumn(variable, 16958 variableProperties, true); 16959 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 16960 relation.setEffectType(EffectType.select); 16961 relation.setTarget(new TableColumnRelationshipElement(variableProperty)); 16962 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 16963 } 16964 } 16965 16966 columnsInExpr visitor = new columnsInExpr(); 16967 column.getExpr().getRightOperand().inOrderTraverse(visitor); 16968 16969 List<TObjectName> objectNames = visitor.getObjectNames(); 16970 List<TParseTreeNode> functions = visitor.getFunctions(); 16971 16972 if (functions != null && !functions.isEmpty()) { 16973 analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.select); 16974 16975 } 16976 16977 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 16978 if (subquerys != null && !subquerys.isEmpty()) { 16979 analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select); 16980 } 16981 16982 analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions); 16983 16984 List<TParseTreeNode> constants = visitor.getConstants(); 16985 analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions); 16986 } else { 16987 if (column.getFieldAttr() != null && isStructColumn(column.getFieldAttr())) { 16988 Table table = modelFactory.createTable(column.getFieldAttr().getSourceTable()); 16989 for (int j = 0; j < table.getColumns().size(); j++) { 16990 TObjectName columnName = new TObjectName(); 16991 if (table.getColumns().get(j).getName().equals(table.getAlias())) { 16992 if (!SQLUtil.isEmpty(column.getColumnAlias())) { 16993 columnName.setString(column.getColumnAlias()); 16994 } else { 16995 columnName.setString(table.getColumns().get(j).getName()); 16996 } 16997 } else { 16998 columnName.setString( 16999 table.getAlias() + "." + table.getColumns().get(j).getName()); 17000 } 17001 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, 17002 columnName); 17003 DataFlowRelationship relationship = modelFactory.createDataFlowRelation(); 17004 relationship.setTarget(new ResultColumnRelationshipElement(resultColumn)); 17005 relationship.addSource( 17006 new TableColumnRelationshipElement(table.getColumns().get(j))); 17007 } 17008 } else if (column.getExpr().getFunctionCall() != null && column.getExpr().getFunctionCall().getFunctionType() == EFunctionType.struct_t) { 17009 Function function = (Function) createFunction(column.getExpr().getFunctionCall()); 17010 String functionName = getResultSetName(function); 17011 for (int j = 0; j < function.getColumns().size(); j++) { 17012 TObjectName columnName = new TObjectName(); 17013 if (column.getAliasClause() != null) { 17014 columnName.setString(column.getAliasClause() + "." 17015 + function.getColumns().get(j).getName()); 17016 } 17017 else { 17018 columnName.setString(functionName + "." 17019 + function.getColumns().get(j).getName()); 17020 } 17021 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, 17022 columnName); 17023 resultColumn.setStruct(true); 17024 DataFlowRelationship relationship = modelFactory.createDataFlowRelation(); 17025 relationship.setTarget(new ResultColumnRelationshipElement(resultColumn)); 17026 relationship.addSource( 17027 new ResultColumnRelationshipElement(function.getColumns().get(j))); 17028 } 17029 } else if (column.getExpr().getFunctionCall() != null && column.getExpr().getFunctionCall().getFunctionType() == EFunctionType.array_t) { 17030 Function function = (Function) createFunction(column.getExpr().getFunctionCall()); 17031 String functionName = getResultSetName(function); 17032 if (function.getColumns().size() == 1) { 17033 // Scalar result inside ARRAY() - use just alias as column name 17034 TObjectName columnName = new TObjectName(); 17035 if (column.getAliasClause() != null) { 17036 columnName.setString(column.getAliasClause().toString()); 17037 } else { 17038 columnName.setString(functionName); 17039 } 17040 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, 17041 columnName); 17042 DataFlowRelationship relationship = modelFactory.createDataFlowRelation(); 17043 relationship.setTarget(new ResultColumnRelationshipElement(resultColumn)); 17044 relationship.addSource( 17045 new ResultColumnRelationshipElement(function.getColumns().get(0))); 17046 } else { 17047 for (int j = 0; j < function.getColumns().size(); j++) { 17048 TObjectName columnName = new TObjectName(); 17049 if (column.getAliasClause() != null) { 17050 columnName.setString(column.getAliasClause() + "." 17051 + getColumnNameOnly(function.getColumns().get(j).getName())); 17052 } 17053 else { 17054 columnName.setString(functionName + "." 17055 + getColumnNameOnly(function.getColumns().get(j).getName())); 17056 } 17057 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, 17058 columnName); 17059 resultColumn.setStruct(true); 17060 DataFlowRelationship relationship = modelFactory.createDataFlowRelation(); 17061 relationship.setTarget(new ResultColumnRelationshipElement(resultColumn)); 17062 relationship.addSource( 17063 new ResultColumnRelationshipElement(function.getColumns().get(j))); 17064 } 17065 } 17066 } else if (column.getExpr().getExprList() != null && column.getExpr().getExpressionType() == EExpressionType.array_t) { 17067 if(column.getExpr().getObjectOperand()!=null) { 17068 TObjectName exprColumnName = column.getExpr().getObjectOperand(); 17069 Table table = modelFactory.createTable(exprColumnName.getSourceTable()); 17070 for (int z = 0; z < table.getColumns().size(); z++) { 17071 TableColumn tableColumn = table.getColumns().get(z); 17072 if(getColumnName(exprColumnName.toString()).equals(getColumnName(tableColumn.getName()))) { 17073 TObjectName columnName = new TObjectName(); 17074 if (column.getAliasClause() != null) { 17075 columnName.setString(column.getAliasClause().toString()); 17076 } else { 17077 columnName 17078 .setString(getColumnNameOnly(columnName.toString())); 17079 } 17080 ResultColumn resultColumn = modelFactory 17081 .createResultColumn(resultSetModel, columnName); 17082 resultColumn.setStruct(true); 17083 DataFlowRelationship relationship = modelFactory 17084 .createDataFlowRelation(); 17085 relationship.setTarget( 17086 new ResultColumnRelationshipElement(resultColumn)); 17087 relationship.addSource(new TableColumnRelationshipElement( 17088 tableColumn)); 17089 } 17090 } 17091 } 17092 else { 17093 for (int j = 0; j < column.getExpr().getExprList().size(); j++) { 17094 TExpression expression = column.getExpr().getExprList().getExpression(j); 17095 if(expression.getExpressionType() == EExpressionType.function_t) { 17096 Function function = (Function)createFunction(expression.getFunctionCall()); 17097 String functionName = getResultSetName(function); 17098 if (function != null && function.getColumns() != null) { 17099 if (function.getColumns().size() == 1) { 17100 // Scalar function inside ARRAY[] (e.g., ARRAY[TO_JSON_STRING(col)]) 17101 // Use just the alias as column name, not alias.functionName 17102 TObjectName columnName = new TObjectName(); 17103 if (column.getAliasClause() != null) { 17104 columnName.setString(column.getAliasClause().toString()); 17105 } else { 17106 columnName.setString(functionName); 17107 } 17108 ResultColumn resultColumn = modelFactory 17109 .createResultColumn(resultSetModel, columnName); 17110 DataFlowRelationship relationship = modelFactory 17111 .createDataFlowRelation(); 17112 relationship.setTarget( 17113 new ResultColumnRelationshipElement(resultColumn)); 17114 relationship.addSource(new ResultColumnRelationshipElement( 17115 function.getColumns().get(0))); 17116 } else { 17117 // Multi-column (struct-like) function - use dotted naming 17118 for (int x = 0; x < function.getColumns().size(); x++) { 17119 TObjectName columnName = new TObjectName(); 17120 if (column.getAliasClause() != null) { 17121 columnName.setString(column.getAliasClause() + "." 17122 + getColumnNameOnly( 17123 function.getColumns().get(x).getName())); 17124 } else { 17125 columnName.setString( 17126 functionName + "." + getColumnNameOnly( 17127 function.getColumns().get(x).getName())); 17128 } 17129 ResultColumn resultColumn = modelFactory 17130 .createResultColumn(resultSetModel, columnName); 17131 resultColumn.setStruct(true); 17132 DataFlowRelationship relationship = modelFactory 17133 .createDataFlowRelation(); 17134 relationship.setTarget( 17135 new ResultColumnRelationshipElement(resultColumn)); 17136 relationship.addSource(new ResultColumnRelationshipElement( 17137 function.getColumns().get(x))); 17138 } 17139 } 17140 } 17141 } 17142 else if(expression.getExpressionType() == EExpressionType.simple_object_name_t) { 17143 TObjectName exprColumnName = expression.getObjectOperand(); 17144 Table table = modelFactory.createTable(exprColumnName.getSourceTable()); 17145 for (int z = 0; z < table.getColumns().size(); z++) { 17146 TableColumn tableColumn = table.getColumns().get(z); 17147 if(getColumnName(exprColumnName.toString()).equals(getColumnName(tableColumn.getName()))) { 17148 TObjectName columnName = new TObjectName(); 17149 if (column.getAliasClause() != null) { 17150 columnName.setString(column.getAliasClause().toString()); 17151 } else { 17152 columnName 17153 .setString(getColumnNameOnly(columnName.toString())); 17154 } 17155 ResultColumn resultColumn = modelFactory 17156 .createResultColumn(resultSetModel, columnName); 17157 resultColumn.setStruct(true); 17158 DataFlowRelationship relationship = modelFactory 17159 .createDataFlowRelation(); 17160 relationship.setTarget( 17161 new ResultColumnRelationshipElement(resultColumn)); 17162 relationship.addSource(new TableColumnRelationshipElement( 17163 tableColumn)); 17164 } 17165 } 17166 } 17167 } 17168 } 17169 } else { 17170 if ("*".equals(column.getColumnNameOnly())) { 17171 Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>(); 17172 Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>(); 17173 if(column.getReplaceExprAsIdentifiers()!=null && column.getReplaceExprAsIdentifiers().size()>0) { 17174 for(TReplaceExprAsIdentifier replace: column.getReplaceExprAsIdentifiers()) { 17175 replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(column.getExpr().getExceptReplaceClause().toString(), replace.getExpr())); 17176 replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier()); 17177 } 17178 } 17179 17180 TObjectName columnObject = column.getFieldAttr(); 17181 List<TTable> sourceTables = columnObject.getSourceTableList(); 17182 if (sourceTables != null && !sourceTables.isEmpty()) { 17183 boolean[] determine = new boolean[sourceTables.size()]; 17184 for (int k = 0; k < sourceTables.size(); k++) { 17185 TTable sourceTable = sourceTables.get(k); 17186 Object tableModel = modelManager.getModel(sourceTable); 17187 if (tableModel instanceof Table && ((Table) tableModel).isCreateTable()) { 17188 Table table = (Table) tableModel; 17189 for (int j = 0; j < table.getColumns().size(); j++) { 17190 TableColumn tableColumn = table.getColumns().get(j); 17191 if (column.getExceptColumnList() != null) { 17192 boolean except = false; 17193 for (TObjectName objectName : column.getExceptColumnList()) { 17194 if(getColumnName(objectName.toString()).equals(getColumnName(tableColumn.getName()))) { 17195 except = true; 17196 break; 17197 } 17198 } 17199 if (!except && tableColumn.isStruct()) { 17200 List<String> names = SQLUtil 17201 .parseNames(tableColumn.getName()); 17202 for (String name : names) { 17203 for (TObjectName objectName : column 17204 .getExceptColumnList()) { 17205 if (getColumnName(objectName.toString()) 17206 .equals(getColumnName(name))) { 17207 except = true; 17208 break; 17209 } 17210 } 17211 if (except) { 17212 break; 17213 } 17214 } 17215 } 17216 if(except){ 17217 continue; 17218 } 17219 } 17220 17221 if (replaceAsIdentifierMap.containsKey(tableColumn.getName())) { 17222 Pair<String, TExpression> expr = replaceAsIdentifierMap.get(tableColumn.getName()); 17223 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, replaceColumnMap.get(tableColumn.getName())); 17224 Transform transform = new Transform(); 17225 transform.setType(Transform.EXPRESSION); 17226 TObjectName expression = new TObjectName(); 17227 expression.setString(expr.first); 17228 transform.setCode(expression); 17229 resultColumn.setTransform(transform); 17230 analyzeResultColumnExpressionRelation(resultColumn, expr.second); 17231 } 17232 else { 17233 String columnName = DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()); 17234 //bigquery 17235 boolean exist = false; 17236 if (!columnName.matches("(?i)f\\d+_")) { 17237 if (!keyMap.containsKey(columnName)) { 17238 keyMap.put(columnName, new AtomicInteger(0)); 17239 } else { 17240 while (columnNames.contains(columnName)) { 17241 if(columnName.indexOf("*") == -1 && stmt.toString().matches("(?is).*using\\s*\\(\\s*"+columnName+"\\s*\\).*")) { 17242 exist = true; 17243 break; 17244 } else if (keyMap.containsKey(columnName)) { 17245 int index = keyMap.get(columnName) 17246 .incrementAndGet(); 17247 columnName = columnName + index; 17248 } 17249 } 17250 } 17251 columnNames.add(columnName); 17252 } 17253 if (exist) { 17254 String targetColumn = columnName; 17255 DataFlowRelationship relation = modelFactory 17256 .createDataFlowRelation(); 17257 relation.setEffectType(EffectType.select); 17258 relation.setTarget(new ResultColumnRelationshipElement( 17259 resultSetModel.getColumns().stream() 17260 .filter(t -> t.getName() 17261 .equalsIgnoreCase(targetColumn)) 17262 .findFirst().get())); 17263 relation.addSource(new TableColumnRelationshipElement( 17264 tableColumn)); 17265 continue; 17266 } 17267 if (DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()) 17268 .equalsIgnoreCase(DlineageUtil.getIdentifierNormalColumnName(columnName))) { 17269 columnName = tableColumn.getName(); 17270 } 17271 ResultColumn resultColumn = modelFactory.createStarResultColumn(resultSetModel, column, columnName); 17272 resultColumn.setStruct(tableColumn.isStruct()); 17273 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17274 relation.setEffectType(EffectType.select); 17275 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 17276 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 17277 } 17278 } 17279 determine[k] = true; 17280 continue; 17281 } 17282 else if (tableModel instanceof ResultSet && ((ResultSet) tableModel).isDetermined()) { 17283 ResultSet table = (ResultSet) tableModel; 17284 for (int j = 0; j < table.getColumns().size(); j++) { 17285 ResultColumn tableColumn = table.getColumns().get(j); 17286 if (column.getExceptColumnList() != null) { 17287 boolean except = false; 17288 for (TObjectName objectName : column.getExceptColumnList()) { 17289 if(getColumnName(objectName.toString()).equals(getColumnName(tableColumn.getName()))) { 17290 except = true; 17291 break; 17292 } 17293 } 17294 if (!except && tableColumn.isStruct()) { 17295 List<String> names = SQLUtil 17296 .parseNames(tableColumn.getName()); 17297 for (String name : names) { 17298 for (TObjectName objectName : column 17299 .getExceptColumnList()) { 17300 if (getColumnName(objectName.toString()) 17301 .equals(getColumnName(name))) { 17302 except = true; 17303 break; 17304 } 17305 } 17306 if (except) { 17307 break; 17308 } 17309 } 17310 } 17311 if(except){ 17312 continue; 17313 } 17314 } 17315 if (replaceAsIdentifierMap.containsKey(tableColumn.getName())) { 17316 Pair<String, TExpression> expr = replaceAsIdentifierMap.get(tableColumn.getName()); 17317 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, replaceColumnMap.get(tableColumn.getName())); 17318 Transform transform = new Transform(); 17319 transform.setType(Transform.EXPRESSION); 17320 TObjectName expression = new TObjectName(); 17321 expression.setString(expr.first); 17322 transform.setCode(expression); 17323 resultColumn.setTransform(transform); 17324 analyzeResultColumnExpressionRelation(resultColumn, expr.second); 17325 } 17326 else if(tableColumn.getRefColumnName()!=null) { 17327 ResultColumn resultColumn = modelFactory.createStarResultColumn(resultSetModel, column, tableColumn.getRefColumnName()); 17328 if(tableColumn.isStruct()) { 17329 resultColumn.setStruct(true); 17330 } 17331 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17332 relation.setEffectType(EffectType.select); 17333 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 17334 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 17335 } 17336 else { 17337 String columnName = DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()); 17338 //bigquery 17339 if (!columnName.matches("(?i)f\\d+_")) { 17340 if (!keyMap.containsKey(columnName)) { 17341 keyMap.put(columnName, new AtomicInteger(0)); 17342 } else { 17343 while (columnNames.contains(columnName)) { 17344 int index = keyMap.get(columnName) 17345 .incrementAndGet(); 17346 columnName = columnName + index; 17347 } 17348 } 17349 columnNames.add(columnName); 17350 } 17351 if (DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()) 17352 .equalsIgnoreCase(DlineageUtil.getIdentifierNormalColumnName(columnName))) { 17353 columnName = tableColumn.getName(); 17354 } 17355 if (modelManager.getModel(column) instanceof ResultColumn) { 17356 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17357 relation.setEffectType(EffectType.select); 17358 relation.setTarget(new ResultColumnRelationshipElement((ResultColumn)modelManager.getModel(column))); 17359 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 17360 } 17361 else { 17362 ResultColumn resultColumn = modelFactory.createStarResultColumn(resultSetModel, column, columnName); 17363 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17364 relation.setEffectType(EffectType.select); 17365 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 17366 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 17367 } 17368 } 17369 } 17370 determine[k] = true; 17371 continue; 17372 } 17373 else { 17374 ResultColumn resultColumn = modelFactory 17375 .createResultColumn(resultSetModel, column); 17376 if (tableModel instanceof Function) { 17377 17378 } else { 17379 TObjectName[] columns = modelManager 17380 .getTableColumns(sourceTable); 17381 for (int j = 0; j < columns.length; j++) { 17382 TObjectName columnName = columns[j]; 17383 if (columnName == null 17384 || "*".equals(getColumnName(columnName))) { 17385 continue; 17386 } 17387 if (isStructColumn(columnName)) { 17388 continue; 17389 } 17390 17391 resultColumn.bindStarLinkColumn(columnName); 17392 if (column.getExceptColumnList() != null) { 17393 for (TObjectName objectName : column 17394 .getExceptColumnList()) { 17395 resultColumn.unbindStarLinkColumn(objectName); 17396 } 17397 } 17398 } 17399 if (tableModel instanceof ResultSet) { 17400 ResultSet queryTable = (ResultSet) tableModel; 17401 if (!containStarColumn(queryTable)) { 17402 resultColumn.setShowStar(false); 17403 } 17404 } 17405 if (tableModel instanceof Table) { 17406 Table table = (Table) tableModel; 17407 if (table.isCreateTable()) { 17408 resultColumn.setShowStar(false); 17409 } 17410 } 17411 } 17412 } 17413 } 17414 if(!Arrays.toString(determine).contains("false")) { 17415 continue; 17416 } 17417 } else { 17418 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, column); 17419 TTableList tables = stmt.getTables(); 17420 for (int k = 0; k < tables.size(); k++) { 17421 TTable table = tables.getTable(k); 17422 TObjectName[] columns = modelManager.getTableColumns(table); 17423 for (int j = 0; j < columns.length; j++) { 17424 TObjectName columnName = columns[j]; 17425 if (columnName == null) { 17426 continue; 17427 } 17428 if ("*".equals(getColumnName(columnName))) { 17429 if (modelManager.getModel(table) instanceof Table) { 17430 Table tableModel = (Table) modelManager.getModel(table); 17431 if (tableModel != null 17432 && !tableModel.getColumns().isEmpty()) { 17433 for (TableColumn item : tableModel.getColumns()) { 17434 resultColumn 17435 .bindStarLinkColumn(item.getColumnObject()); 17436 if (table.getSubquery() == null 17437 && table.getCTE() == null 17438 && !tableModel.isCreateTable()) { 17439 resultColumn.setShowStar(true); 17440 } 17441 } 17442 } 17443 } else if (modelManager.getModel(table) instanceof QueryTable) { 17444 QueryTable tableModel = (QueryTable) modelManager 17445 .getModel(table); 17446 if (tableModel != null 17447 && !tableModel.getColumns().isEmpty()) { 17448 for (ResultColumn item : tableModel.getColumns()) { 17449 if (item.hasStarLinkColumn()) { 17450 for (TObjectName starLinkColumn : item 17451 .getStarLinkColumnList()) { 17452 resultColumn 17453 .bindStarLinkColumn(starLinkColumn); 17454 } 17455 } else if (item 17456 .getColumnObject() instanceof TObjectName) { 17457 resultColumn.bindStarLinkColumn( 17458 (TObjectName) item.getColumnObject()); 17459 } else if (item 17460 .getColumnObject() instanceof TResultColumn) { 17461 TResultColumn queryTableColumn = (TResultColumn) item 17462 .getColumnObject(); 17463 TObjectName tableColumnObject = queryTableColumn 17464 .getFieldAttr(); 17465 if (tableColumnObject != null) { 17466 resultColumn.bindStarLinkColumn( 17467 tableColumnObject); 17468 } else if (queryTableColumn 17469 .getAliasClause() != null && !item.isStruct()) { 17470 resultColumn.bindStarLinkColumn( 17471 queryTableColumn.getAliasClause() 17472 .getAliasName()); 17473 } 17474 } 17475 } 17476 } 17477 } 17478 continue; 17479 } 17480 resultColumn.bindStarLinkColumn(columnName); 17481 } 17482 } 17483 } 17484 isDetermined = false; 17485 } 17486 else { 17487 if(column.getAliasClause()!=null && column.getAliasClause().getColumns()!=null) { 17488 for(TObjectName aliasColumn: column.getAliasClause().getColumns()) { 17489 modelFactory.createResultColumn(resultSetModel, aliasColumn); 17490 } 17491 } 17492 else { 17493 modelFactory.createResultColumn(resultSetModel, column); 17494 } 17495 } 17496 analyzeResultColumn(column, EffectType.select); 17497 } 17498 } 17499 } 17500 if (isDetermined) { 17501 resultSetModel.setDetermined(isDetermined); 17502 } 17503 } 17504 17505 TSelectSqlStatement parent = getParentSetSelectStmt(stmt); 17506 if (parent != null && parent.getSetOperatorType() != ESetOperatorType.none) { 17507 ResultSet resultSetModel = modelFactory.createResultSet(stmt, false); 17508 if(queryModel == null) { 17509 queryModel = resultSetModel; 17510 } 17511 17512 createPseudoImpactRelation(stmt, resultSetModel, EffectType.select); 17513 17514 boolean isDetermined = true; 17515 for (int i = 0; i < stmt.getResultColumnList().size(); i++) { 17516 TResultColumn column = stmt.getResultColumnList().getResultColumn(i); 17517 if ("*".equals(column.getColumnNameOnly())) { 17518 17519 Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>(); 17520 Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>(); 17521 if(column.getReplaceExprAsIdentifiers()!=null && column.getReplaceExprAsIdentifiers().size()>0) { 17522 for(TReplaceExprAsIdentifier replace: column.getReplaceExprAsIdentifiers()) { 17523 replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(column.getExpr().getExceptReplaceClause().toString(), replace.getExpr())); 17524 replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier()); 17525 } 17526 } 17527 17528 TObjectName columnObject = column.getFieldAttr(); 17529 TTable sourceTable = columnObject.getSourceTable(); 17530 if (sourceTable != null) { 17531 Object tableModel = modelManager.getModel(sourceTable); 17532 if (tableModel instanceof Table && ((Table) tableModel).isCreateTable()) { 17533 Table table = (Table) tableModel; 17534 for (int j = 0; j < table.getColumns().size(); j++) { 17535 TableColumn tableColumn = table.getColumns().get(j); 17536 if (column.getExceptColumnList() != null) { 17537 boolean except = false; 17538 for (TObjectName objectName : column.getExceptColumnList()) { 17539 if (getColumnName(objectName.toString()) 17540 .equals(getColumnName(tableColumn.getName()))) { 17541 except = true; 17542 break; 17543 } 17544 } 17545 if (!except && tableColumn.isStruct()) { 17546 List<String> names = SQLUtil 17547 .parseNames(tableColumn.getName()); 17548 for (String name : names) { 17549 for (TObjectName objectName : column 17550 .getExceptColumnList()) { 17551 if (getColumnName(objectName.toString()) 17552 .equals(getColumnName(name))) { 17553 except = true; 17554 break; 17555 } 17556 } 17557 if (except) { 17558 break; 17559 } 17560 } 17561 } 17562 if (except) { 17563 continue; 17564 } 17565 } 17566 17567 if (replaceAsIdentifierMap.containsKey(tableColumn.getName())) { 17568 Pair<String, TExpression> expr = replaceAsIdentifierMap.get(tableColumn.getName()); 17569 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, replaceColumnMap.get(tableColumn.getName())); 17570 Transform transform = new Transform(); 17571 transform.setType(Transform.EXPRESSION); 17572 TObjectName expression = new TObjectName(); 17573 expression.setString(expr.first); 17574 transform.setCode(expression); 17575 resultColumn.setTransform(transform); 17576 analyzeResultColumnExpressionRelation(resultColumn, expr.second); 17577 } 17578 else { 17579 ResultColumn resultColumn = modelFactory.createStarResultColumn( 17580 resultSetModel, column, tableColumn.getName()); 17581 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17582 relation.setEffectType(EffectType.select); 17583 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 17584 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 17585 } 17586 } 17587 continue; 17588 } else if (tableModel instanceof ResultSet 17589 && ((ResultSet) tableModel).isDetermined()) { 17590 ResultSet table = (ResultSet) tableModel; 17591 for (int j = 0; j < table.getColumns().size(); j++) { 17592 ResultColumn tableColumn = table.getColumns().get(j); 17593 if (column.getExceptColumnList() != null) { 17594 boolean except = false; 17595 for (TObjectName objectName : column.getExceptColumnList()) { 17596 if (getColumnName(objectName.toString()) 17597 .equals(getColumnName(tableColumn.getName()))) { 17598 except = true; 17599 break; 17600 } 17601 } 17602 if (!except && tableColumn.isStruct()) { 17603 List<String> names = SQLUtil 17604 .parseNames(tableColumn.getName()); 17605 for (String name : names) { 17606 for (TObjectName objectName : column 17607 .getExceptColumnList()) { 17608 if (getColumnName(objectName.toString()) 17609 .equals(getColumnName(name))) { 17610 except = true; 17611 break; 17612 } 17613 } 17614 if (except) { 17615 break; 17616 } 17617 } 17618 } 17619 if (except) { 17620 continue; 17621 } 17622 } 17623 17624 if (replaceAsIdentifierMap.containsKey(tableColumn.getName())) { 17625 Pair<String, TExpression> expr = replaceAsIdentifierMap.get(tableColumn.getName()); 17626 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, replaceColumnMap.get(tableColumn.getName())); 17627 Transform transform = new Transform(); 17628 transform.setType(Transform.EXPRESSION); 17629 TObjectName expression = new TObjectName(); 17630 expression.setString(expr.first); 17631 transform.setCode(expression); 17632 resultColumn.setTransform(transform); 17633 analyzeResultColumnExpressionRelation(resultColumn, expr.second); 17634 } 17635 else if (tableColumn.getRefColumnName() != null) { 17636 ResultColumn resultColumn = modelFactory.createStarResultColumn( 17637 (ResultSet)queryModel, column, tableColumn.getRefColumnName()); 17638 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17639 relation.setEffectType(EffectType.select); 17640 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 17641 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 17642 } else { 17643 ResultColumn resultColumn = modelFactory.createStarResultColumn( 17644 resultSetModel, column, tableColumn.getName()); 17645 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17646 relation.setEffectType(EffectType.select); 17647 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 17648 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 17649 } 17650 } 17651 continue; 17652 } 17653 else { 17654 isDetermined = false; 17655 } 17656 } 17657 17658 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, column); 17659 17660 if (columnObject.getTableToken() != null && sourceTable != null) { 17661 TObjectName[] columns = modelManager.getTableColumns(sourceTable); 17662 for (int j = 0; j < columns.length; j++) { 17663 TObjectName columnName = columns[j]; 17664 if (columnName == null || "*".equals(getColumnName(columnName))) { 17665 continue; 17666 } 17667 resultColumn.bindStarLinkColumn(columnName); 17668 } 17669 17670 if (modelManager.getModel(sourceTable) instanceof Table) { 17671 Table tableModel = (Table) modelManager.getModel(sourceTable); 17672 if (tableModel != null && !tableModel.getColumns().isEmpty()) { 17673 for (TableColumn item : tableModel.getColumns()) { 17674 if ("*".equals(getColumnName(item.getColumnObject()))) { 17675 continue; 17676 } 17677 resultColumn.bindStarLinkColumn(item.getColumnObject()); 17678 } 17679 } 17680 } else if (modelManager.getModel(sourceTable) instanceof QueryTable) { 17681 QueryTable tableModel = (QueryTable) modelManager.getModel(sourceTable); 17682 if (tableModel != null && !tableModel.getColumns().isEmpty()) { 17683 for (ResultColumn item : tableModel.getColumns()) { 17684 if (item.hasStarLinkColumn()) { 17685 for (TObjectName starLinkColumn : item.getStarLinkColumnList()) { 17686 if ("*".equals(getColumnName(starLinkColumn))) { 17687 continue; 17688 } 17689 resultColumn.bindStarLinkColumn(starLinkColumn); 17690 } 17691 } else if (item.getColumnObject() instanceof TObjectName) { 17692 TObjectName starLinkColumn = (TObjectName) item.getColumnObject(); 17693 if ("*".equals(getColumnName(starLinkColumn))) { 17694 continue; 17695 } 17696 resultColumn.bindStarLinkColumn(starLinkColumn); 17697 } 17698 } 17699 } 17700 } 17701 17702 } else { 17703 TTableList tables = stmt.getTables(); 17704 for (int k = 0; k < tables.size(); k++) { 17705 TTable table = tables.getTable(k); 17706 TObjectName[] columns = modelManager.getTableColumns(table); 17707 for (int j = 0; j < columns.length; j++) { 17708 TObjectName columnName = columns[j]; 17709 if (columnName == null) { 17710 continue; 17711 } 17712 if ("*".equals(getColumnName(columnName))) { 17713 if (modelManager.getModel(table) instanceof Table) { 17714 Table tableModel = (Table) modelManager.getModel(table); 17715 if (tableModel != null && !tableModel.getColumns().isEmpty()) { 17716 for (TableColumn item : tableModel.getColumns()) { 17717 resultColumn.bindStarLinkColumn(item.getColumnObject()); 17718 } 17719 } 17720 } else if (modelManager.getModel(table) instanceof QueryTable) { 17721 QueryTable tableModel = (QueryTable) modelManager.getModel(table); 17722 if (tableModel != null && !tableModel.getColumns().isEmpty()) { 17723 for (ResultColumn item : tableModel.getColumns()) { 17724 if (item.hasStarLinkColumn()) { 17725 for (TObjectName starLinkColumn : item 17726 .getStarLinkColumnList()) { 17727 resultColumn.bindStarLinkColumn(starLinkColumn); 17728 } 17729 } else if (item.getColumnObject() instanceof TObjectName) { 17730 resultColumn.bindStarLinkColumn( 17731 (TObjectName) item.getColumnObject()); 17732 } else if (item 17733 .getColumnObject() instanceof TResultColumn) { 17734 TResultColumn queryTableColumn = (TResultColumn) item 17735 .getColumnObject(); 17736 TObjectName tableColumnObject = queryTableColumn 17737 .getFieldAttr(); 17738 if (tableColumnObject != null) { 17739 resultColumn.bindStarLinkColumn(tableColumnObject); 17740 } else if (queryTableColumn.getAliasClause() != null) { 17741 resultColumn.bindStarLinkColumn(queryTableColumn 17742 .getAliasClause().getAliasName()); 17743 } 17744 } 17745 } 17746 } 17747 } 17748 17749 continue; 17750 } 17751 resultColumn.bindStarLinkColumn(columnName); 17752 } 17753 } 17754 } 17755 } 17756 else { 17757 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, column); 17758 } 17759 analyzeResultColumn(column, EffectType.select); 17760 17761 } 17762 17763 resultSetModel.setDetermined(isDetermined); 17764 } 17765 } else { 17766 for (int i = 0; i < stmt.getResultColumnList().size(); i++) { 17767 TResultColumn column = stmt.getResultColumnList().getResultColumn(i); 17768 17769 if (!(queryModel instanceof ResultSet)) { 17770 continue; 17771 } 17772 17773 ResultSet resultSetModel = (ResultSet)queryModel; 17774 17775 if ("*".equals(column.getColumnNameOnly())) { 17776 TObjectName columnObject = column.getFieldAttr(); 17777 TTable sourceTable = columnObject.getSourceTable(); 17778 if (column.toString().indexOf(".") == -1 && stmt.getTables().size() > 1) { 17779 sourceTable = null; 17780 } 17781 if (sourceTable != null) { 17782 { 17783 Object tableModel = modelManager.getModel(sourceTable); 17784 if (tableModel instanceof Table && ((Table) tableModel).isCreateTable()) { 17785 Table table = (Table) tableModel; 17786 for (int j = 0; j < table.getColumns().size(); j++) { 17787 TableColumn tableColumn = table.getColumns().get(j); 17788 if (column.getExceptColumnList() != null) { 17789 boolean except = false; 17790 for (TObjectName objectName : column.getExceptColumnList()) { 17791 if (getColumnName(objectName.toString()) 17792 .equals(getColumnName(tableColumn.getName()))) { 17793 except = true; 17794 break; 17795 } 17796 } 17797 if (!except && tableColumn.isStruct()) { 17798 List<String> names = SQLUtil 17799 .parseNames(tableColumn.getName()); 17800 for (String name : names) { 17801 for (TObjectName objectName : column 17802 .getExceptColumnList()) { 17803 if (getColumnName(objectName.toString()) 17804 .equals(getColumnName(name))) { 17805 except = true; 17806 break; 17807 } 17808 } 17809 if (except) { 17810 break; 17811 } 17812 } 17813 } 17814 if (except) { 17815 continue; 17816 } 17817 } 17818 ResultColumn resultColumn = modelFactory.createStarResultColumn( 17819 resultSetModel, column, tableColumn.getName()); 17820 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17821 relation.setEffectType(EffectType.select); 17822 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 17823 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 17824 } 17825 if(stmt.getResultColumnList().size() == 1) { 17826 resultSetModel.setDetermined(true); 17827 } 17828 else { 17829 int starCount = 0; 17830 for (int j = 0; j < stmt.getResultColumnList().size(); j++) { 17831 if (stmt.getResultColumnList().getResultColumn(j).getColumnNameOnly() 17832 .endsWith("*")) { 17833 starCount += 1; 17834 } 17835 } 17836 if (starCount <= 1) { 17837 resultSetModel.setDetermined(true); 17838 } 17839 } 17840 continue; 17841 } else if (tableModel instanceof ResultSet 17842 && ((ResultSet) tableModel).isDetermined()) { 17843 ResultSet table = (ResultSet) tableModel; 17844 for (int j = 0; j < table.getColumns().size(); j++) { 17845 ResultColumn tableColumn = table.getColumns().get(j); 17846 if (column.getExceptColumnList() != null) { 17847 boolean except = false; 17848 for (TObjectName objectName : column.getExceptColumnList()) { 17849 if (getColumnName(objectName.toString()) 17850 .equals(getColumnName(tableColumn.getName()))) { 17851 except = true; 17852 break; 17853 } 17854 } 17855 if (!except && tableColumn.isStruct()) { 17856 List<String> names = SQLUtil 17857 .parseNames(tableColumn.getName()); 17858 for (String name : names) { 17859 for (TObjectName objectName : column 17860 .getExceptColumnList()) { 17861 if (getColumnName(objectName.toString()) 17862 .equals(getColumnName(name))) { 17863 except = true; 17864 break; 17865 } 17866 } 17867 if (except) { 17868 break; 17869 } 17870 } 17871 } 17872 if (except) { 17873 continue; 17874 } 17875 } 17876 if (tableColumn.getRefColumnName() != null) { 17877 ResultColumn resultColumn = modelFactory.createStarResultColumn( 17878 (ResultSet)queryModel, column, tableColumn.getRefColumnName()); 17879 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17880 relation.setEffectType(EffectType.select); 17881 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 17882 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 17883 } else { 17884 ResultColumn resultColumn = modelFactory.createStarResultColumn( 17885 resultSetModel, column, tableColumn.getName()); 17886 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 17887 relation.setEffectType(EffectType.select); 17888 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 17889 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 17890 } 17891 } 17892 if(stmt.getResultColumnList().size() == 1) { 17893 resultSetModel.setDetermined(true); 17894 } 17895 else { 17896 int starCount = 0; 17897 for (int j = 0; j < stmt.getResultColumnList().size(); j++) { 17898 if (stmt.getResultColumnList().getResultColumn(j).getColumnNameOnly() 17899 .endsWith("*")) { 17900 starCount += 1; 17901 } 17902 } 17903 if (starCount <= 1) { 17904 resultSetModel.setDetermined(true); 17905 } 17906 } 17907 continue; 17908 } 17909 } 17910 17911 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, column); 17912 if (modelManager.getModel(sourceTable) instanceof Table) { 17913 Table tableModel = (Table) modelManager.getModel(sourceTable); 17914 if (tableModel != null) { 17915 modelFactory.createTableColumn(tableModel, columnObject, false); 17916 } 17917 TObjectName[] columns = modelManager.getTableColumns(sourceTable); 17918 for (int j = 0; j < columns.length; j++) { 17919 TObjectName columnName = columns[j]; 17920 if (columnName == null || "*".equals(getColumnName(columnName))) { 17921 continue; 17922 } 17923 resultColumn.bindStarLinkColumn(columnName); 17924 } 17925 17926 if (tableModel.getColumns() != null) { 17927 for (int j = 0; j < tableModel.getColumns().size(); j++) { 17928 TableColumn tableColumn = tableModel.getColumns().get(j); 17929 TObjectName columnName = tableColumn.getColumnObject(); 17930 if (columnName == null || "*".equals(getColumnName(columnName))) { 17931 continue; 17932 } 17933 resultColumn.bindStarLinkColumn(columnName); 17934 } 17935 } 17936 } else if (modelManager.getModel(sourceTable) instanceof QueryTable) { 17937 QueryTable tableModel = (QueryTable) modelManager.getModel(sourceTable); 17938 if (tableModel != null && !tableModel.getColumns().isEmpty()) { 17939 for (ResultColumn item : tableModel.getColumns()) { 17940 if (item.hasStarLinkColumn()) { 17941 for (TObjectName starLinkColumn : item.getStarLinkColumnList()) { 17942 resultColumn.bindStarLinkColumn(starLinkColumn); 17943 } 17944 } else if (item.getColumnObject() instanceof TObjectName) { 17945 resultColumn.bindStarLinkColumn((TObjectName) item.getColumnObject()); 17946 } else if (item.getColumnObject() instanceof TResultColumn) { 17947 TResultColumn queryTableColumn = (TResultColumn) item.getColumnObject(); 17948 TObjectName tableColumnObject = queryTableColumn.getFieldAttr(); 17949 if (tableColumnObject != null) { 17950 resultColumn.bindStarLinkColumn(tableColumnObject); 17951 } else if (queryTableColumn.getAliasClause() != null) { 17952 resultColumn.bindStarLinkColumn( 17953 queryTableColumn.getAliasClause().getAliasName()); 17954 } 17955 } 17956 } 17957 } 17958 } 17959 } else { 17960 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, column); 17961 TTableList tables = stmt.getTables(); 17962 for (int k = 0; k < tables.size(); k++) { 17963 TTable table = tables.getTable(k); 17964 TObjectName[] columns = modelManager.getTableColumns(table); 17965 for (int j = 0; j < columns.length; j++) { 17966 TObjectName columnName = columns[j]; 17967 if (columnName == null) { 17968 continue; 17969 } 17970 if ("*".equals(getColumnName(columnName))) { 17971 if (modelManager.getModel(table) instanceof Table) { 17972 Table tableModel = (Table) modelManager.getModel(table); 17973 if (tableModel != null) { 17974 modelFactory.createTableColumn(tableModel, columnName, false); 17975 } 17976 if (tableModel != null && !tableModel.getColumns().isEmpty()) { 17977 for (int z = 0; z < tableModel.getColumns().size(); z++) { 17978 resultColumn.bindStarLinkColumn( 17979 tableModel.getColumns().get(z).getColumnObject()); 17980 } 17981 } 17982 } else if (modelManager.getModel(table) instanceof QueryTable) { 17983 QueryTable tableModel = (QueryTable) modelManager.getModel(table); 17984 if (tableModel != null && !tableModel.getColumns().isEmpty()) { 17985 for (ResultColumn item : tableModel.getColumns()) { 17986 if (item.hasStarLinkColumn()) { 17987 for (TObjectName starLinkColumn : item 17988 .getStarLinkColumnList()) { 17989 resultColumn.bindStarLinkColumn(starLinkColumn); 17990 } 17991 } else if (item.getColumnObject() instanceof TObjectName) { 17992 resultColumn.bindStarLinkColumn( 17993 (TObjectName) item.getColumnObject()); 17994 } else if (item.getColumnObject() instanceof TResultColumn) { 17995 TResultColumn queryTableColumn = (TResultColumn) item 17996 .getColumnObject(); 17997 TObjectName tableColumnObject = queryTableColumn 17998 .getFieldAttr(); 17999 if (tableColumnObject != null) { 18000 resultColumn.bindStarLinkColumn(tableColumnObject); 18001 } else if (queryTableColumn.getAliasClause() != null) { 18002 resultColumn.bindStarLinkColumn(queryTableColumn 18003 .getAliasClause().getAliasName()); 18004 } 18005 } 18006 } 18007 } 18008 } 18009 continue; 18010 } 18011 resultColumn.bindStarLinkColumn(columnName); 18012 } 18013 } 18014 } 18015 } 18016 else { 18017 ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, column); 18018 } 18019 18020 analyzeResultColumn(column, EffectType.select); 18021 18022 } 18023 18024 if (queryModel instanceof ResultSet) { 18025 boolean isDetermined = true; 18026 ResultSet resultSet = (ResultSet) queryModel; 18027 for (ResultColumn column : resultSet.getColumns()) { 18028 if (column.getName().endsWith("*")) { 18029 isDetermined = false; 18030 break; 18031 } 18032 } 18033 if (isDetermined) { 18034 resultSet.setDetermined(isDetermined); 18035 } 18036 } 18037 } 18038 } 18039 18040 18041 analyzeSelectIntoClause(stmt); 18042 18043 18044 if (stmt.getJoins() != null && stmt.getJoins().size() > 0) { 18045 for (int i = 0; i < stmt.getJoins().size(); i++) { 18046 TJoin join = stmt.getJoins().getJoin(i); 18047 ResultSet topResultSet = (ResultSet) modelManager.getModel(stmt); 18048 if (join.getJoinItems() != null && join.getJoinItems().size() > 0) { 18049 for (int k = 0; k < join.getJoinItems().size(); k++) { 18050 TTable table = join.getJoinItems().getJoinItem(k).getTable(); 18051 if (table != null && table.getSubquery() != null) { 18052 18053 ResultSet joinResultSet = (ResultSet) modelManager.getModel(table.getSubquery()); 18054 for (int x = 0; x < joinResultSet.getColumns().size(); x++) { 18055 ResultColumn sourceColumn = joinResultSet.getColumns().get(x); 18056 ResultColumn resultColumn = matchResultColumn(topResultSet.getColumns(), 18057 sourceColumn); 18058 if (resultColumn != null 18059 && resultColumn.getColumnObject() instanceof TResultColumn) { 18060 TResultColumn column = (TResultColumn) resultColumn.getColumnObject(); 18061 if (column.getAliasClause() == null && column.getFieldAttr() != null) { 18062 TObjectName resultObject = column.getFieldAttr(); 18063 if (resultObject.getSourceTable() == null 18064 || resultObject.getSourceTable().equals(table)) { 18065 DataFlowRelationship combinedQueryRelation = modelFactory 18066 .createDataFlowRelation(); 18067 combinedQueryRelation.setEffectType(EffectType.select); 18068 combinedQueryRelation 18069 .setTarget(new ResultColumnRelationshipElement(resultColumn)); 18070 combinedQueryRelation 18071 .addSource(new ResultColumnRelationshipElement(sourceColumn)); 18072 } 18073 } 18074 } 18075 } 18076 } 18077 18078 if(join.getJoinItems().getJoinItem(k).getJoin()!=null) { 18079 analyzeJoin(join.getJoinItems().getJoinItem(k).getJoin(), EffectType.select); 18080 } 18081 } 18082 } 18083 analyzeJoin(join, EffectType.select); 18084 } 18085 } 18086 18087 if (stmt.getWhereClause() != null) { 18088 TExpression expr = stmt.getWhereClause().getCondition(); 18089 if (expr != null) { 18090 analyzeFilterCondition(null, expr, null, JoinClauseType.where, EffectType.select); 18091 } 18092 } 18093 18094 stmtStack.pop(); 18095 } 18096 } 18097 18098 protected TObjectNameList getTableLinkedColumns(TTable table) { 18099 if(structObjectMap.containsKey(table)) { 18100 return structObjectMap.get(table); 18101 } 18102 return table.getLinkedColumns(); 18103 } 18104 18105 protected boolean isTopResultSet(TSelectSqlStatement stmt) { 18106 TCustomSqlStatement parent = stmt.getParentStmt(); 18107 if (parent == null) 18108 return true; 18109 if (parent instanceof TMssqlReturn) { 18110 return true; 18111 } 18112 if (parent instanceof TReturnStmt) { 18113 return true; 18114 } 18115 if (parent instanceof TCommonBlock) { 18116 TCommonBlock block = (TCommonBlock) parent; 18117 if (block.getStatements() != null) { 18118 for (int i = 0; i < block.getStatements().size(); i++) { 18119 TCustomSqlStatement child = block.getStatements().get(i); 18120 if(stmt == child) { 18121 return true; 18122 } 18123 } 18124 } 18125 } 18126 if (parent instanceof TMssqlBlock) { 18127 TMssqlBlock block = (TMssqlBlock) parent; 18128 if (block.getStatements() != null) { 18129 for (int i = 0; i < block.getStatements().size(); i++) { 18130 TCustomSqlStatement child = block.getStatements().get(i); 18131 if(stmt == child) { 18132 return true; 18133 } 18134 } 18135 } 18136 } 18137 if (parent instanceof TStoredProcedureSqlStatement) { 18138 TStoredProcedureSqlStatement block = (TStoredProcedureSqlStatement) parent; 18139 if (block.getStatements() != null) { 18140 for (int i = 0; i < block.getStatements().size(); i++) { 18141 TCustomSqlStatement child = block.getStatements().get(i); 18142 if(child == stmt) { 18143 return true; 18144 } 18145 if (child instanceof TReturnStmt) { 18146 TReturnStmt returnStmt = (TReturnStmt) child; 18147 if (returnStmt.getStatements() != null) { 18148 for (int j = 0; j < returnStmt.getStatements().size(); j++) { 18149 TCustomSqlStatement child1 = returnStmt.getStatements().get(j); 18150 if(child1 == stmt) { 18151 return true; 18152 } 18153 } 18154 } 18155 } 18156 if (child instanceof TMssqlReturn) { 18157 TMssqlReturn returnStmt = (TMssqlReturn) child; 18158 if (returnStmt.getStatements() != null) { 18159 for (int j = 0; j < returnStmt.getStatements().size(); j++) { 18160 TCustomSqlStatement child1 = returnStmt.getStatements().get(j); 18161 if(child1 == stmt) { 18162 return true; 18163 } 18164 } 18165 } 18166 } 18167 } 18168 } 18169 } 18170 return false; 18171 } 18172 18173 protected void analyzeTableSubquery(TTable table) { 18174 if(table.getSubquery()!=null) { 18175 QueryTable queryTable = modelFactory.createQueryTable(table); 18176 TSelectSqlStatement subquery = table.getSubquery(); 18177 analyzeSelectStmt(subquery); 18178 18179 ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery); 18180 18181 if (resultSetModel != null && resultSetModel != queryTable 18182 && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 18183 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 18184 impactRelation.setEffectType(EffectType.select); 18185 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 18186 resultSetModel.getRelationRows())); 18187 impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 18188 queryTable.getRelationRows())); 18189 } 18190 18191 if (resultSetModel != null && resultSetModel != queryTable 18192 && queryTable.getTableObject().getAliasClause() != null 18193 && queryTable.getTableObject().getAliasClause().getColumns() != null) { 18194 for (int j = 0; j < queryTable.getColumns().size() 18195 && j < resultSetModel.getColumns().size(); j++) { 18196 ResultColumn sourceColumn = resultSetModel.getColumns().get(j); 18197 ResultColumn targetColumn = queryTable.getColumns().get(j); 18198 18199 DataFlowRelationship queryRalation = modelFactory.createDataFlowRelation(); 18200 queryRalation.setEffectType(EffectType.select); 18201 queryRalation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 18202 queryRalation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 18203 } 18204 } else if (subquery.getSetOperatorType() != ESetOperatorType.none) { 18205 SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager 18206 .getModel(subquery); 18207 for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) { 18208 ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j); 18209 ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable, 18210 sourceColumn); 18211 for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) { 18212 targetColumn.bindStarLinkColumn(starLinkColumn); 18213 } 18214 DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation(); 18215 selectSetRalation.setEffectType(EffectType.select); 18216 selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 18217 selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 18218 } 18219 } 18220 } 18221 } 18222 18223 private ResultColumn getPivotedTableColumn(TPivotedTable pivotedTable, TObjectName columnName) { 18224 List<TPivotClause> pivotClauses = new ArrayList<TPivotClause>(); 18225 if (pivotedTable.getPivotClause() != null) { 18226 pivotClauses.add(pivotedTable.getPivotClause()); 18227 } 18228 if (pivotedTable.getPivotClauseList() != null) { 18229 for (int i = 0; i < pivotedTable.getPivotClauseList().size(); i++) { 18230 pivotClauses.add(pivotedTable.getPivotClauseList().getElement(i)); 18231 } 18232 } 18233 for (TPivotClause clause : pivotClauses) { 18234 Object model = modelManager.getModel(clause); 18235 if (model instanceof PivotedTable) { 18236 PivotedTable pivotedTableModel = (PivotedTable) model; 18237 if (pivotedTableModel.getColumns() != null) { 18238 for (ResultColumn column : pivotedTableModel.getColumns()) { 18239 if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName), 18240 getColumnName(SQLUtil.trimColumnStringQuote(column.getName())))) { 18241 return column; 18242 } 18243 } 18244 } 18245 } 18246 } 18247 return null; 18248 } 18249 18250 private void analyzeHiveTransformClause(TSelectSqlStatement stmt, THiveTransformClause transformClause) { 18251 Table mapSourceTable = null; 18252 QueryTable mapQueryTable = null; 18253 if(stmt.getTables()!=null) { 18254 for(int i=0;i<stmt.getTables().size();i++) { 18255 TTable table = stmt.getTables().getTable(i); 18256 if (table.getSubquery() != null) { 18257 if (transformClause.getTransformType() == ETransformType.ettReduce) { 18258 mapQueryTable = modelFactory.createQueryTable(table); 18259 } 18260 analyzeSelectStmt(table.getSubquery()); 18261 } 18262 else { 18263 mapSourceTable = modelFactory.createTable(table); 18264 } 18265 } 18266 } 18267 18268 if (transformClause.getTransformType() == ETransformType.ettReduce) { 18269 modelFactory.createResultSet(stmt, false); 18270 } 18271 18272 List<TableColumn> mapTableColumns = new ArrayList<TableColumn>(); 18273 List<ResultColumn> mapResultSetColumns = new ArrayList<ResultColumn>(); 18274 List<ResultColumn> redueResultSetColumns = new ArrayList<ResultColumn>(); 18275 18276 if(transformClause.getExpressionList()!=null) { 18277 for(TExpression expression: transformClause.getExpressionList()) { 18278 if(expression.getObjectOperand()!=null) { 18279 if (transformClause.getTransformType() == ETransformType.ettMap || transformClause.getTransformType() == ETransformType.ettSelect) { 18280 if (mapSourceTable != null) { 18281 TableColumn tableColumn = modelFactory.createTableColumn(mapSourceTable, 18282 expression.getObjectOperand(), false); 18283 if (tableColumn != null) { 18284 mapTableColumns.add(tableColumn); 18285 } 18286 } 18287 } 18288 else if (transformClause.getTransformType() == ETransformType.ettReduce) { 18289 if (mapQueryTable != null) { 18290 ResultColumn resultColumn = modelFactory.createResultColumn(mapQueryTable, 18291 expression.getObjectOperand(), false); 18292 if (resultColumn != null) { 18293 mapResultSetColumns.add(resultColumn); 18294 } 18295 } 18296 } 18297 } 18298 } 18299 } 18300 18301 if (transformClause.getAliasClause() != null) { 18302 Object model = modelManager.getModel(stmt); 18303 if (model instanceof ResultSet) { 18304 ResultSet result = (ResultSet) model; 18305 if (result!=null && transformClause.getAliasClause().getColumns() != null) { 18306 for (TObjectName column : transformClause.getAliasClause().getColumns()) { 18307 ResultColumn resultColumn = modelFactory.createResultColumn(result, column); 18308 if (resultColumn != null) { 18309 if (transformClause.getTransformType() == ETransformType.ettMap 18310 || transformClause.getTransformType() == ETransformType.ettSelect) { 18311 mapResultSetColumns.add(resultColumn); 18312 } 18313 else if (transformClause.getTransformType() == ETransformType.ettReduce) { 18314 redueResultSetColumns.add(resultColumn); 18315 } 18316 } 18317 } 18318 } 18319 } 18320 } 18321 18322 if (transformClause.getTransformType() == ETransformType.ettMap 18323 || transformClause.getTransformType() == ETransformType.ettSelect) { 18324 if (!mapTableColumns.isEmpty() && !mapResultSetColumns.isEmpty()) { 18325 for (ResultColumn resultColumn : mapResultSetColumns) { 18326 for (TableColumn tableColumn : mapTableColumns) { 18327 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18328 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 18329 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 18330 relation.setEffectType(EffectType.select); 18331 } 18332 } 18333 } 18334 } 18335 else if (transformClause.getTransformType() == ETransformType.ettReduce) { 18336 if (!redueResultSetColumns.isEmpty() && !mapResultSetColumns.isEmpty()) { 18337 for (ResultColumn reduceResultColumn : redueResultSetColumns) { 18338 for (ResultColumn mapResultColumn : mapResultSetColumns) { 18339 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18340 relation.setTarget(new ResultColumnRelationshipElement(reduceResultColumn)); 18341 relation.addSource(new ResultColumnRelationshipElement(mapResultColumn)); 18342 relation.setEffectType(EffectType.select); 18343 } 18344 } 18345 } 18346 } 18347 } 18348 18349 protected boolean isStructColumn(TObjectName columnName) { 18350 return columnName.getSourceTable() != null && columnName.getSourceTable().getAliasClause() != null 18351 && columnName.getSourceTable().getUnnestClause() != null 18352 && DlineageUtil.compareColumnIdentifier(getColumnName(columnName), 18353 getColumnName(columnName.getSourceTable().getAliasClause().getAliasName())); 18354 } 18355 18356 private TObjectName getObjectName(ResultColumn column) { 18357 if (column.getColumnObject() instanceof TResultColumn) { 18358 TResultColumn resultColumn = (TResultColumn) column.getColumnObject(); 18359 if (resultColumn.getAliasClause() != null && resultColumn.getAliasClause().getAliasName() != null) { 18360 return resultColumn.getAliasClause().getAliasName(); 18361 } 18362 if (resultColumn.getFieldAttr() != null) { 18363 return resultColumn.getFieldAttr(); 18364 } 18365 if (resultColumn.getExpr() != null 18366 && resultColumn.getExpr().getExpressionType() == EExpressionType.simple_object_name_t) { 18367 return resultColumn.getExpr().getObjectOperand(); 18368 } 18369 } else if (column.getColumnObject() instanceof TObjectName) { 18370 return (TObjectName) column.getColumnObject(); 18371 } 18372 return null; 18373 } 18374 18375 private boolean isShowTopSelectResultSet() { 18376 if (option.isSimpleOutput() && !option.isSimpleShowTopSelectResultSet()) 18377 return false; 18378 return true; 18379 } 18380 18381 private void analyzeSelectIntoClause(TSelectSqlStatement stmt) { 18382 if (stmt.getParentStmt() instanceof TSelectSqlStatement) { 18383 return; 18384 } 18385 18386 TableColumn oracleIntoTableColumn = null; 18387 18388 TIntoClause intoClause = stmt.getIntoClause(); 18389 18390 TSelectSqlStatement leftStmt = DlineageUtil.getLeftStmt(stmt); 18391 18392 if (intoClause == null && leftStmt != null) { 18393 intoClause = leftStmt.getIntoClause(); 18394 } 18395 18396 if (intoClause != null) { 18397 List<TObjectName> tableNames = new ArrayList<TObjectName>(); 18398 if (intoClause.getExprList() != null) { 18399 for (int j = 0; j < intoClause.getExprList().size(); j++) { 18400 TObjectName tableName = intoClause.getExprList().getExpression(j).getObjectOperand(); 18401 if (tableName != null) { 18402 if (tableName.toString().startsWith(":") && option.getVendor() == EDbVendor.dbvoracle 18403 && tableName.getDbObjectType() == EDbObjectType.column) { 18404 TObjectName tableAlias = new TObjectName(); 18405 tableAlias.setString(tableName.getTableString()); 18406 tableNames.add(tableAlias); 18407 TTable sourceTable = tableName.getSourceTable(); 18408 Table sourceTableModel = modelFactory.createTable(sourceTable, tableAlias); 18409 oracleIntoTableColumn = modelFactory.createTableColumn(sourceTableModel, tableName, true); 18410 } else { 18411 if (tableName != null) { 18412 tableNames.add(tableName); 18413 } 18414 } 18415 } 18416 else if(intoClause.getExprList().getExpression(j).getFunctionCall()!=null) { 18417 TObjectName variableName = intoClause.getExprList().getExpression(j).getFunctionCall().getFunctionName(); 18418 tableNames.add(variableName); 18419 Variable variable = modelFactory.createVariable(variableName); 18420 variable.setSubType(SubType.record); 18421 TObjectName variableProperties = new TObjectName(); 18422 variableProperties.setString("*"); 18423 modelFactory.createTableColumn(variable, variableProperties, true); 18424 } 18425 } 18426 } else if (intoClause.getVariableList() != null) { 18427 for (int j = 0; j < intoClause.getVariableList().size(); j++) { 18428 TObjectName tableName = intoClause.getVariableList().getObjectName(j); 18429 if (tableName != null) { 18430 tableNames.add(tableName); 18431 } 18432 } 18433 } else if (intoClause.getIntoName() != null) { 18434 tableNames.add(intoClause.getIntoName()); 18435 } 18436 18437 ResultSet queryModel = (ResultSet) modelManager.getModel(stmt.getResultColumnList()); 18438 if (stmt.getSetOperatorType() != ESetOperatorType.none) { 18439 queryModel = (ResultSet) modelManager.getModel(stmt); 18440 } 18441 for (int j = 0; j < tableNames.size(); j++) { 18442 TObjectName tableName = tableNames.get(j); 18443 if (tableName.getColumnNameOnly().startsWith("@") 18444 && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) { 18445 continue; 18446 } 18447 18448 if (tableName.getColumnNameOnly().startsWith(":") 18449 && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) { 18450 continue; 18451 } 18452 18453 Table tableModel; 18454 TableColumn variableColumn = null; 18455 18456 if (tableName.getDbObjectType() == EDbObjectType.variable) { 18457 if (tableName.toString().indexOf(".") != -1) { 18458 List<String> splits = SQLUtil.parseNames(tableName.toString()); 18459 tableModel = modelFactory.createVariable(splits.get(splits.size() - 2)); 18460 } else { 18461 tableModel = modelFactory.createVariable(tableName); 18462 } 18463 if (tableModel.getSubType() == null) { 18464 tableModel.setSubType(SubType.record); 18465 } 18466 if(tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) { 18467 TObjectName variableProperties = new TObjectName(); 18468 variableProperties.setString("*"); 18469 variableColumn = modelFactory.createTableColumn(tableModel, variableProperties, true); 18470 } 18471 } else { 18472 tableModel = modelFactory.createTableByName(tableName); 18473 // SELECT ... INTO <table> creates the target. Parse fact, set 18474 // regardless of isDetermined() (unlike the gated setCreateTable 18475 // below). See dlineage-authoritative-endpoint-classification.md. 18476 tableModel.setCreatedInSql(true); 18477 tableModel.setEndpointIntroduction(EndpointIntroduction.SELECT_INTO); 18478 } 18479 18480 if (queryModel instanceof ResultSet && (stmt.getWhereClause() != null || hasJoin(stmt))) { 18481 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 18482 impactRelation.setEffectType(EffectType.insert); 18483 impactRelation.addSource( 18484 new RelationRowsRelationshipElement<ResultSetRelationRows>(((ResultSet)queryModel).getRelationRows())); 18485 impactRelation.setTarget( 18486 new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows())); 18487 } 18488 18489 Process process = modelFactory.createProcess(stmt); 18490 tableModel.addProcess(process); 18491 18492 if (stmt.getSetOperatorType() != ESetOperatorType.none) { 18493 for (ResultColumn resultColumn : queryModel.getColumns()) { 18494 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 18495 resultColumn.getName()); 18496 18497 if (DlineageUtil.isTempTable(tableModel, option.getVendor()) && sqlenv != null 18498 && tableModel.getDatabase() != null && tableModel.getSchema() != null) { 18499 TSQLSchema schema = sqlenv 18500 .getSQLSchema(tableModel.getDatabase() + "." + tableModel.getSchema(), true); 18501 if (schema != null) { 18502 TSQLTable tempTable = schema 18503 .createTable(DlineageUtil.getSimpleTableName(tableModel.getName())); 18504 tempTable.addColumn(tableColumn.getName()); 18505 } 18506 } 18507 18508 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18509 relation.setEffectType(EffectType.insert); 18510 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 18511 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 18512 relation.setProcess(process); 18513 } 18514 18515 tableModel.setDetermined(queryModel.isDetermined()); 18516 if(queryModel.isDetermined() && DlineageUtil.isTempTable(tableModel, option.getVendor())) { 18517 tableModel.setCreateTable(true, false); 18518 } 18519 return; 18520 } 18521 18522 boolean isDetermined = true; 18523 for (int i = 0; i < stmt.getResultColumnList().size(); i++) { 18524 if (tableNames.size() > 1 && tableName.getDbObjectType() == EDbObjectType.variable) { 18525 if (i != j) { 18526 continue; 18527 } 18528 } 18529 TResultColumn column = stmt.getResultColumnList().getResultColumn(i); 18530 18531 if ("*".equals(column.getColumnNameOnly()) && column.getFieldAttr() != null 18532 && column.getFieldAttr().getSourceTable() != null) { 18533 Object model = modelManager.getModel(column); 18534 if(model instanceof LinkedHashMap) { 18535 LinkedHashMap<String, ResultColumn> columns = (LinkedHashMap<String, ResultColumn>)model; 18536 for(String key: columns.keySet()) { 18537 ResultColumn sourceColumn = columns.get(key); 18538 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 18539 sourceColumn.getName()); 18540 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18541 relation.setEffectType(EffectType.insert); 18542 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 18543 relation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 18544 relation.setProcess(process); 18545 } 18546 } 18547 else if(model instanceof ResultColumn) { 18548 isDetermined = false; 18549 ResultColumn resultColumn = (ResultColumn) model; 18550 List<TObjectName> columns = resultColumn.getStarLinkColumnList(); 18551 if (columns.size() > 0) { 18552 for (int k = 0; k < columns.size(); k++) { 18553 18554 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 18555 columns.get(k)); 18556 18557 if (DlineageUtil.isTempTable(tableModel, option.getVendor()) && sqlenv != null 18558 && tableModel.getDatabase() != null && tableModel.getSchema() != null) { 18559 TSQLSchema schema = sqlenv.getSQLSchema( 18560 tableModel.getDatabase() + "." + tableModel.getSchema(), true); 18561 if (schema != null) { 18562 TSQLTable tempTable = schema.createTable(DlineageUtil.getSimpleTableName(tableModel.getName())); 18563 tempTable.addColumn(tableColumn.getName()); 18564 } 18565 } 18566 18567 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18568 relation.setEffectType(EffectType.insert); 18569 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 18570 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 18571 relation.setProcess(process); 18572 } 18573 if (resultColumn.isShowStar()) { 18574 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 18575 column.getFieldAttr()); 18576 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18577 relation.setEffectType(EffectType.insert); 18578 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 18579 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 18580 relation.setProcess(process); 18581 } 18582 } else { 18583 TObjectName columnObject = column.getFieldAttr(); 18584 if (column.getAliasClause() != null) { 18585 columnObject = column.getAliasClause().getAliasName(); 18586 } 18587 if (columnObject != null) { 18588 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 18589 columnObject); 18590 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18591 relation.setEffectType(EffectType.insert); 18592 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 18593 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 18594 relation.setProcess(process); 18595 } else if (!SQLUtil.isEmpty(column.getColumnAlias())) { 18596 TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, 18597 column.getAliasClause().getAliasName()); 18598 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18599 relation.setEffectType(EffectType.insert); 18600 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 18601 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 18602 relation.setProcess(process); 18603 } 18604 } 18605 } 18606 } else { 18607 ResultColumn resultColumn = null; 18608 18609 if (queryModel instanceof QueryTable) { 18610 resultColumn = (ResultColumn) modelManager.getModel(column); 18611 } else if (queryModel instanceof ResultSet) { 18612 resultColumn = (ResultColumn) modelManager.getModel(column); 18613 } else { 18614 continue; 18615 } 18616 18617 if (resultColumn == null && column.getAliasClause() != null) { 18618 resultColumn = (ResultColumn) modelManager.getModel(column.getAliasClause().getAliasName()); 18619 } 18620 18621 if (resultColumn != null) { 18622 TObjectName columnObject = column.getFieldAttr(); 18623 if (column.getAliasClause() != null) { 18624 columnObject = column.getAliasClause().getAliasName(); 18625 } 18626 TableColumn tableColumn = null; 18627 if (columnObject != null) { 18628 if (tableModel.isVariable()) { 18629 if (variableColumn != null) { 18630 tableColumn = variableColumn; 18631 } else { 18632 tableColumn = tableModel.getColumns().get(0); 18633 } 18634 } 18635 else if (oracleIntoTableColumn != null) { 18636 tableColumn = oracleIntoTableColumn; 18637 } 18638 else { 18639 tableColumn = modelFactory.createInsertTableColumn(tableModel, columnObject); 18640 if (containStarColumn(queryModel)) { 18641 tableColumn.notBindStarLinkColumn(true); 18642 } 18643 } 18644 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18645 relation.setEffectType(EffectType.insert); 18646 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 18647 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 18648 relation.setProcess(process); 18649 } else if (!SQLUtil.isEmpty(column.getColumnAlias())) { 18650 if (tableModel.isVariable()) { 18651 if (variableColumn != null) { 18652 tableColumn = variableColumn; 18653 } else { 18654 tableColumn = tableModel.getColumns().get(0); 18655 } 18656 } else { 18657 tableColumn = modelFactory.createInsertTableColumn(tableModel, 18658 column.getAliasClause().getAliasName()); 18659 } 18660 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18661 relation.setEffectType(EffectType.insert); 18662 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 18663 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 18664 relation.setProcess(process); 18665 } else { 18666 if (tableModel.isVariable()) { 18667 if (variableColumn != null) { 18668 tableColumn = variableColumn; 18669 } else { 18670 tableColumn = tableModel.getColumns().get(0); 18671 } 18672 } 18673 if (tableColumn != null) { 18674 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18675 relation.setEffectType(EffectType.insert); 18676 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 18677 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 18678 relation.setProcess(process); 18679 } 18680 } 18681 } 18682 } 18683 } 18684 tableModel.setDetermined(isDetermined); 18685 if(isDetermined && DlineageUtil.isTempTable(tableModel, option.getVendor())) { 18686 tableModel.setCreateTable(true, false); 18687 } 18688 } 18689 } 18690 } 18691 18692 private boolean isUnPivotedTable(TPivotedTable pivotedTable) { 18693 if (pivotedTable.getPivotClauseList() != null && pivotedTable.getPivotClauseList().size() > 0) { 18694 return pivotedTable.getPivotClauseList().getElement(0).getType() == TPivotClause.unpivot; 18695 } else { 18696 TPivotClause pivotClause = pivotedTable.getPivotClause(); 18697 return pivotClause.getType() == TPivotClause.unpivot; 18698 } 18699 } 18700 18701 private void analyzeUnPivotedTable(TSelectSqlStatement stmt, TPivotedTable pivotedTable) { 18702 List<Object> tables = new ArrayList<Object>(); 18703 Set<Object> pivotedColumns = new HashSet<Object>(); 18704 TTable fromTable = pivotedTable.getTableSource(); 18705 Object table = modelManager.getModel(fromTable); 18706 List<TPivotClause> pivotClauses = new ArrayList<TPivotClause>(); 18707 if (pivotedTable.getPivotClauseList() != null && pivotedTable.getPivotClauseList().size() > 0) { 18708 for (int i = 0; i < pivotedTable.getPivotClauseList().size(); i++) { 18709 pivotClauses.add(pivotedTable.getPivotClauseList().getElement(i)); 18710 } 18711 } else { 18712 TPivotClause pivotClause = pivotedTable.getPivotClause(); 18713 pivotClauses.add(pivotClause); 18714 } 18715 18716 for (int y = 0; y < pivotClauses.size(); y++) { 18717 TPivotClause pivotClause = pivotClauses.get(y); 18718 PivotedTable pivotTable = modelFactory.createPivotdTable(pivotClause); 18719 pivotTable.setUnpivoted(true); 18720 18721 if (pivotClause.getValueColumnList() != null) { 18722 for (int j = 0; j < pivotClause.getValueColumnList().size(); j++) { 18723 modelFactory.createResultColumn(pivotTable, pivotClause.getValueColumnList().getObjectName(j)); 18724 } 18725 } 18726 if (pivotClause.getPivotColumnList() != null) { 18727 for (int j = 0; j < pivotClause.getPivotColumnList().size(); j++) { 18728 modelFactory.createResultColumn(pivotTable, pivotClause.getPivotColumnList().getObjectName(j)); 18729 } 18730 } 18731 if (pivotClause.getUnpivotInClause()!=null && pivotClause.getUnpivotInClause().getItems() != null) { 18732 for (int j = 0; j < pivotClause.getUnpivotInClause().getItems().size(); j++) { 18733 TObjectName columnName = pivotClause.getUnpivotInClause().getItems().getElement(j).getColumn(); 18734 if (columnName != null) { 18735 if (table instanceof QueryTable) { 18736 for (ResultColumn tableColumn : ((QueryTable) table).getColumns()) { 18737 if (getColumnName(columnName) 18738 .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 18739 for (ResultColumn resultColumn : pivotTable.getColumns()) { 18740 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18741 relation.setEffectType(EffectType.select); 18742 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 18743 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 18744 pivotedColumns.add(tableColumn); 18745 } 18746 break; 18747 } 18748 } 18749 } else if (table instanceof Table) { 18750 for (TableColumn tableColumn : ((Table) table).getColumns()) { 18751 if (getColumnName(columnName) 18752 .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 18753 for (ResultColumn resultColumn : pivotTable.getColumns()) { 18754 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18755 relation.setEffectType(EffectType.select); 18756 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 18757 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 18758 pivotedColumns.add(tableColumn); 18759 } 18760 break; 18761 } 18762 } 18763 } 18764 } else { 18765 TObjectNameList columnNames = pivotClause.getUnpivotInClause().getItems().getElement(j) 18766 .getColumnList(); 18767 for (TObjectName columnName1 : columnNames) { 18768 if (table instanceof QueryTable) { 18769 for (ResultColumn tableColumn : ((QueryTable) table).getColumns()) { 18770 if (getColumnName(columnName1).equals( 18771 DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 18772 for (ResultColumn resultColumn : pivotTable.getColumns()) { 18773 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18774 relation.setEffectType(EffectType.select); 18775 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 18776 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 18777 pivotedColumns.add(tableColumn); 18778 } 18779 break; 18780 } 18781 } 18782 } else if (table instanceof Table) { 18783 for (TableColumn tableColumn : ((Table) table).getColumns()) { 18784 if (getColumnName(columnName1).equals( 18785 DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 18786 for (ResultColumn resultColumn : pivotTable.getColumns()) { 18787 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18788 relation.setEffectType(EffectType.select); 18789 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 18790 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 18791 pivotedColumns.add(tableColumn); 18792 } 18793 break; 18794 } 18795 } 18796 } 18797 } 18798 } 18799 } 18800 } 18801 tables.add(pivotTable); 18802 tables.add(table); 18803 } 18804 18805 ResultSet resultSet = modelFactory.createResultSet(stmt, 18806 isTopResultSet(stmt) && isShowTopSelectResultSet()); 18807 TResultColumnList columnList = stmt.getResultColumnList(); 18808 for (int i = 0; i < columnList.size(); i++) { 18809 TResultColumn column = columnList.getResultColumn(i); 18810 ResultColumn resultColumn = modelFactory.createAndBindingSelectSetResultColumn(resultSet, column, i); 18811 if (resultColumn.getColumnObject() instanceof TResultColumn) { 18812 TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject(); 18813 if (columnObject.getFieldAttr() != null) { 18814 if ("*".equals(getColumnName(columnObject.getFieldAttr()))) { 18815 resultColumn.setShowStar(false); 18816 int index = 0; 18817 for (int k = 0; k < tables.size(); k++) { 18818 Object tableItem = tables.get(k); 18819 if (tableItem instanceof ResultSet) { 18820 for (int x = 0; x < ((ResultSet) tableItem).getColumns().size(); x++) { 18821 ResultColumn tableColumn = ((ResultSet) tableItem).getColumns().get(x); 18822 if (pivotedColumns.contains(tableColumn)) { 18823 continue; 18824 } 18825 if (tableColumn.getColumnObject() instanceof TObjectName) { 18826 resultColumn.bindStarLinkColumn((TObjectName) tableColumn.getColumnObject()); 18827 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18828 relation.setEffectType(EffectType.select); 18829 relation.setTarget(new ResultColumnRelationshipElement(resultColumn, (TObjectName) tableColumn.getColumnObject())); 18830 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 18831 } else if (tableColumn.getColumnObject() instanceof TResultColumn) { 18832 if (((TResultColumn) tableColumn.getColumnObject()).getFieldAttr() != null) { 18833 if (tableColumn.hasStarLinkColumn()) { 18834 for (int z = 0; z < tableColumn.getStarLinkColumnList().size(); z++) { 18835 ResultColumn resultColumn1 = modelFactory.createResultColumn( 18836 (ResultSet) tableItem, 18837 tableColumn.getStarLinkColumnList().get(z)); 18838 DataFlowRelationship relation = modelFactory 18839 .createDataFlowRelation(); 18840 relation.setEffectType(EffectType.select); 18841 relation.setTarget( 18842 new ResultColumnRelationshipElement(resultColumn)); 18843 relation.addSource( 18844 new ResultColumnRelationshipElement(resultColumn1)); 18845 tableColumn.getStarLinkColumns().remove( 18846 getColumnName(tableColumn.getStarLinkColumnList().get(z))); 18847 z--; 18848 } 18849 } else { 18850 resultColumn.bindStarLinkColumn( 18851 ((TResultColumn) tableColumn.getColumnObject()).getFieldAttr()); 18852 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18853 relation.setEffectType(EffectType.select); 18854 relation.setTarget(new ResultColumnRelationshipElement(resultColumn, ((TResultColumn) tableColumn.getColumnObject()).getFieldAttr())); 18855 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 18856 } 18857 } else if (((TResultColumn) tableColumn.getColumnObject()).getExpr() != null) { 18858 TExpression expr = ((TResultColumn) tableColumn.getColumnObject()) 18859 .getExpr(); 18860 if (expr.getExpressionType() == EExpressionType.simple_constant_t) { 18861 TObjectName columnName = new TObjectName(); 18862 columnName.setString(expr.toString()); 18863 resultColumn.bindStarLinkColumn(columnName); 18864 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18865 relation.setEffectType(EffectType.select); 18866 relation.setTarget(new ResultColumnRelationshipElement(resultColumn, columnName)); 18867 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 18868 } 18869 } 18870 } 18871 } 18872 } else if (tableItem instanceof Table) { 18873 for (TableColumn tableColumn : ((Table) tableItem).getColumns()) { 18874 if (pivotedColumns.contains(tableColumn)) { 18875 continue; 18876 } 18877 resultColumn.bindStarLinkColumn((TObjectName) tableColumn.getColumnObject(), index); 18878 index++; 18879 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18880 relation.setEffectType(EffectType.select); 18881 relation.setTarget(new ResultColumnRelationshipElement(resultColumn, (TObjectName) tableColumn.getColumnObject())); 18882 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 18883 } 18884 } 18885 } 18886 } else { 18887 for (int k = 0; k < tables.size(); k++) { 18888 Object tableItem = tables.get(k); 18889 if (tableItem instanceof ResultSet) { 18890 for (ResultColumn tableColumn : ((ResultSet) tableItem).getColumns()) { 18891 if (getColumnName(columnObject.getFieldAttr()).equals( 18892 DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 18893 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18894 relation.setEffectType(EffectType.select); 18895 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 18896 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 18897 break; 18898 } 18899 } 18900 } else if (tableItem instanceof Table) { 18901 for (TableColumn tableColumn : ((Table) tableItem).getColumns()) { 18902 if (getColumnName(columnObject.getFieldAttr()).equals( 18903 DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 18904 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18905 relation.setEffectType(EffectType.select); 18906 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 18907 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 18908 break; 18909 } 18910 } 18911 } 18912 } 18913 } 18914 } else if (columnObject.getExpr() != null) { 18915 analyzeResultColumn(column, EffectType.select); 18916 } 18917 } 18918 } 18919 } 18920 18921 private void analyzePivotedTable(TSelectSqlStatement stmt, TPivotedTable pivotedTable) { 18922 List<Object> tables = new ArrayList<Object>(); 18923 Set<Object> pivotedColumns = new HashSet<Object>(); 18924 TTable fromTable = pivotedTable.getTableSource(); 18925 Object table = modelManager.getModel(fromTable); 18926 if(table == null && fromTable.getSubquery()!=null) { 18927 table = modelFactory.createQueryTable(fromTable); 18928 TSelectSqlStatement subquery = fromTable.getSubquery(); 18929 analyzeSelectStmt(subquery); 18930 } 18931 List<TPivotClause> pivotClauses = new ArrayList<TPivotClause>(); 18932 if (pivotedTable.getPivotClauseList() != null && pivotedTable.getPivotClauseList().size() > 0) { 18933 for (int i = 0; i < pivotedTable.getPivotClauseList().size(); i++) { 18934 pivotClauses.add(pivotedTable.getPivotClauseList().getElement(i)); 18935 } 18936 } else { 18937 TPivotClause pivotClause = pivotedTable.getPivotClause(); 18938 pivotClauses.add(pivotClause); 18939 } 18940 18941 for (int y = 0; y < pivotClauses.size(); y++) { 18942 TPivotClause pivotClause = pivotClauses.get(y); 18943 List<TFunctionCall> functionCalls = new ArrayList<TFunctionCall>(); 18944 if (pivotClause.getAggregation_function() != null || pivotClause.getAggregation_function_list() != null) { 18945 if (pivotClause.getAggregation_function() != null) { 18946 functionCalls.add((TFunctionCall) pivotClause.getAggregation_function()); 18947 } else if (pivotClause.getAggregation_function_list() != null) { 18948 for (int i = 0; i < pivotClause.getAggregation_function_list().size(); i++) { 18949 functionCalls.add((TFunctionCall) pivotClause.getAggregation_function_list().getResultColumn(i) 18950 .getExpr().getFunctionCall()); 18951 } 18952 } 18953 18954 if (functionCalls.isEmpty()) { 18955 return; 18956 } 18957 18958 if (pivotClause.getPivotColumnList() == null) { 18959 return; 18960 } 18961 18962 if (pivotClause.getPivotInClause() == null) { 18963 return; 18964 } 18965 18966 for (int x = 0; x < functionCalls.size(); x++) { 18967 TFunctionCall functionCall = functionCalls.get(x); 18968 Function function = modelFactory.createFunction(functionCall); 18969 ResultColumn column = modelFactory.createFunctionResultColumn(function, 18970 ((TFunctionCall) functionCall).getFunctionName()); 18971 18972 List<TExpression> expressions = new ArrayList<TExpression>(); 18973 getFunctionExpressions(expressions, new ArrayList<TExpression>(), functionCall); 18974 18975 for (int j = 0; j < expressions.size(); j++) { 18976 columnsInExpr visitor = new columnsInExpr(); 18977 expressions.get(j).inOrderTraverse(visitor); 18978 List<TObjectName> objectNames = visitor.getObjectNames(); 18979 if (objectNames == null) { 18980 continue; 18981 } 18982 for (TObjectName columnName : objectNames) { 18983 if (table instanceof QueryTable) { 18984 for (int i = 0; i < ((QueryTable) table).getColumns().size(); i++) { 18985 boolean find = false; 18986 ResultColumn tableColumn = ((QueryTable) table).getColumns().get(i); 18987 if (tableColumn.hasStarLinkColumn()) { 18988 for (int k = 0; k < tableColumn.getStarLinkColumnList().size(); k++) { 18989 TObjectName objectName = tableColumn.getStarLinkColumnList().get(k); 18990 if (getColumnName(columnName).equals(getColumnName(objectName))) { 18991 ResultColumn resultColumn = modelFactory 18992 .createResultColumn((QueryTable) table, objectName); 18993 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 18994 relation.setEffectType(EffectType.select); 18995 relation.setTarget(new ResultColumnRelationshipElement(column)); 18996 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 18997 pivotedColumns.add(resultColumn); 18998 tableColumn.getStarLinkColumns() 18999 .remove(DlineageUtil.getColumnName(objectName)); 19000 find = true; 19001 break; 19002 } 19003 } 19004 } else if (getColumnName(columnName).equals( 19005 DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 19006 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19007 relation.setEffectType(EffectType.select); 19008 relation.setTarget(new ResultColumnRelationshipElement(column)); 19009 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 19010 pivotedColumns.add(tableColumn); 19011 find = true; 19012 break; 19013 } 19014 19015 if (!find && tableColumn.getName().endsWith("*")) { 19016 QueryTable queryTable = (QueryTable)table; 19017 ResultColumn resultColumn = modelFactory.createResultColumn(queryTable, columnName); 19018 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19019 relation.setEffectType(EffectType.select); 19020 relation.setTarget(new ResultColumnRelationshipElement(column)); 19021 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 19022 tableColumn.bindStarLinkColumn(columnName); 19023 } 19024 } 19025 } else if (table instanceof Table) { 19026 for (TableColumn tableColumn : ((Table) table).getColumns()) { 19027 if (getColumnName(columnName).equals( 19028 DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 19029 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19030 relation.setEffectType(EffectType.select); 19031 relation.setTarget(new ResultColumnRelationshipElement(column)); 19032 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 19033 pivotedColumns.add(tableColumn); 19034 break; 19035 } 19036 } 19037 } 19038 } 19039 } 19040 19041 PivotedTable pivotTable = modelFactory.createPivotdTable(pivotClause); 19042 pivotTable.setUnpivoted(false); 19043 19044 if (pivotClause.getPivotInClause().getItems() != null) { 19045 for (int j = 0; j < pivotClause.getPivotInClause().getItems().size(); j++) { 19046 ResultColumn resultColumn = null; 19047 if (pivotClause.getAggregation_function_list() != null 19048 && pivotClause.getAggregation_function_list().size() > 1) { 19049 TResultColumn functionColumn = pivotClause.getAggregation_function_list() 19050 .getResultColumn(x); 19051 TObjectName tableColumn = new TObjectName(); 19052 if (option.getVendor() == EDbVendor.dbvbigquery) { 19053 tableColumn.setString(getResultColumnString(functionColumn) + "_" 19054 + SQLUtil.trimColumnStringQuote(getResultColumnString( 19055 pivotClause.getPivotInClause().getItems().getResultColumn(j)))); 19056 } 19057 else { 19058 tableColumn.setString(SQLUtil 19059 .trimColumnStringQuote(getResultColumnString( 19060 pivotClause.getPivotInClause().getItems().getResultColumn(j))) 19061 + "_" + getResultColumnString(functionColumn)); 19062 } 19063 resultColumn = modelFactory.createResultColumn(pivotTable, tableColumn); 19064 } else { 19065 resultColumn = modelFactory.createSelectSetResultColumn(pivotTable, 19066 pivotClause.getPivotInClause().getItems().getResultColumn(j), j); 19067 } 19068 { 19069 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19070 relation.setEffectType(EffectType.select); 19071 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 19072 relation.addSource(new ResultColumnRelationshipElement(column)); 19073 } 19074 { 19075 for (TObjectName columnName : pivotClause.getPivotColumnList()) { 19076 if (table instanceof QueryTable) { 19077 for (int i = 0; i < ((QueryTable) table).getColumns().size(); i++) { 19078 ResultColumn tableColumn = ((QueryTable) table).getColumns().get(i); 19079 if (tableColumn.hasStarLinkColumn()) { 19080 for (int k = 0; k < tableColumn.getStarLinkColumnList().size(); k++) { 19081 TObjectName objectName = tableColumn.getStarLinkColumnList().get(k); 19082 if (getColumnName(columnName).equals(getColumnName(objectName))) { 19083 ResultColumn resultColumn1 = modelFactory 19084 .createResultColumn((QueryTable) table, objectName); 19085 DataFlowRelationship relation = modelFactory 19086 .createDataFlowRelation(); 19087 relation.setEffectType(EffectType.select); 19088 relation.setTarget(new ResultColumnRelationshipElement(column)); 19089 relation.addSource( 19090 new ResultColumnRelationshipElement(resultColumn1)); 19091 pivotedColumns.add(resultColumn1); 19092 tableColumn.getStarLinkColumns() 19093 .remove(DlineageUtil.getColumnName(objectName)); 19094 break; 19095 } 19096 } 19097 } else if (getColumnName(columnName).equals(DlineageUtil 19098 .getIdentifierNormalColumnName(tableColumn.getName()))) { 19099 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19100 relation.setEffectType(EffectType.select); 19101 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 19102 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 19103 pivotedColumns.add(tableColumn); 19104 break; 19105 } 19106 } 19107 } else if (table instanceof Table) { 19108 for (TableColumn tableColumn : ((Table) table).getColumns()) { 19109 if (getColumnName(columnName).equals(DlineageUtil 19110 .getIdentifierNormalColumnName(tableColumn.getName()))) { 19111 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19112 relation.setEffectType(EffectType.select); 19113 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 19114 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 19115 pivotedColumns.add(tableColumn); 19116 break; 19117 } 19118 } 19119 } 19120 } 19121 } 19122 } 19123 } else if (pivotClause.getPivotInClause().getSubQuery() != null) { 19124 TSelectSqlStatement subquery = pivotClause.getPivotInClause().getSubQuery(); 19125 analyzeSelectStmt(subquery); 19126 ResultSet selectSetResultSetModel = (ResultSet) modelManager.getModel(subquery); 19127 for (int j = 0; j < subquery.getResultColumnList().size(); j++) { 19128 ResultColumn resultColumn = modelFactory.createSelectSetResultColumn(pivotTable, 19129 subquery.getResultColumnList().getResultColumn(j), j); 19130 { 19131 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19132 relation.setEffectType(EffectType.select); 19133 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 19134 relation.addSource(new ResultColumnRelationshipElement(column)); 19135 relation.addSource(new ResultColumnRelationshipElement( 19136 selectSetResultSetModel.getColumns().get(j))); 19137 } 19138 { 19139 for (TObjectName columnName : pivotClause.getPivotColumnList()) { 19140 if (table instanceof QueryTable) { 19141 for (ResultColumn tableColumn : ((QueryTable) table).getColumns()) { 19142 if (getColumnName(columnName).equals(DlineageUtil 19143 .getIdentifierNormalColumnName(tableColumn.getName()))) { 19144 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19145 relation.setEffectType(EffectType.select); 19146 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 19147 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 19148 pivotedColumns.add(tableColumn); 19149 break; 19150 } 19151 } 19152 } else if (table instanceof Table) { 19153 for (TableColumn tableColumn : ((Table) table).getColumns()) { 19154 if (getColumnName(columnName).equals(DlineageUtil 19155 .getIdentifierNormalColumnName(tableColumn.getName()))) { 19156 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19157 relation.setEffectType(EffectType.select); 19158 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 19159 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 19160 pivotedColumns.add(tableColumn); 19161 break; 19162 } 19163 } 19164 } 19165 } 19166 } 19167 } 19168 } 19169 tables.add(pivotTable); 19170 tables.add(table); 19171 } 19172 } 19173 } 19174 19175 TPivotClause pivotClause = pivotClauses.get(0); 19176 boolean hasAlias = pivotClause.getAliasClause() != null && pivotClause.getAliasClause().getColumns() != null 19177 && pivotClause.getAliasClause().getColumns().size() > 0; 19178 if (hasAlias) { 19179 Alias alias = modelFactory.createAlias(pivotClause.getAliasClause()); 19180 List<TObjectName> aliasColumns = new ArrayList<TObjectName>(); 19181 int index = 0; 19182 for (int k = 0; k < tables.size(); k++) { 19183 Object tableItem = tables.get(k); 19184 if (tableItem instanceof ResultSet) { 19185 for (ResultColumn tableColumn : ((ResultSet) tableItem).getColumns()) { 19186 if (pivotedColumns.contains(tableColumn)) { 19187 continue; 19188 } 19189 if (tableColumn.getColumnObject() instanceof TObjectName) { 19190 aliasColumns.add((TObjectName) tableColumn.getColumnObject()); 19191 } else if (tableColumn.getColumnObject() instanceof TResultColumn) { 19192 if (((TResultColumn) tableColumn.getColumnObject()).getFieldAttr() != null) { 19193 aliasColumns.add(((TResultColumn) tableColumn.getColumnObject()).getFieldAttr()); 19194 } else { 19195 TExpression expr = ((TResultColumn) tableColumn.getColumnObject()).getExpr(); 19196 if (expr.getExpressionType() == EExpressionType.simple_constant_t) { 19197 TObjectName columnName = new TObjectName(); 19198 columnName.setString(expr.toString()); 19199 aliasColumns.add(columnName); 19200 } 19201 } 19202 } 19203 } 19204 } else if (tableItem instanceof Table) { 19205 for (TableColumn tableColumn : ((Table) tableItem).getColumns()) { 19206 if (pivotedColumns.contains(tableColumn)) { 19207 continue; 19208 } 19209 aliasColumns.add(index, (TObjectName) tableColumn.getColumnObject()); 19210 index++; 19211 } 19212 } 19213 } 19214 19215 IndexedLinkedHashMap<String, ResultColumn> aliasColumnMap = new IndexedLinkedHashMap<String, ResultColumn>(); 19216 int diffCount = pivotClause.getAliasClause().getColumns().size() - aliasColumns.size(); 19217 for (int k = 0; k < pivotClause.getAliasClause().getColumns().size(); k++) { 19218 if (pivotClause.getAliasClause().getColumns().size() > aliasColumns.size()) { 19219 if (k < diffCount) { 19220 continue; 19221 } 19222 ResultColumn resultColumn = modelFactory.createResultColumn(alias, 19223 pivotClause.getAliasClause().getColumns().getObjectName(k)); 19224 if ((k - diffCount) < aliasColumns.size()) { 19225 aliasColumnMap.put(aliasColumns.get(k - diffCount).toString(), resultColumn); 19226 } 19227 } else { 19228 ResultColumn resultColumn = modelFactory.createResultColumn(alias, 19229 pivotClause.getAliasClause().getColumns().getObjectName(k)); 19230 if (k < aliasColumns.size()) { 19231 aliasColumnMap.put(aliasColumns.get(k).toString(), resultColumn); 19232 } 19233 } 19234 } 19235 19236 for (int k = 0; k < tables.size(); k++) { 19237 Object tableItem = tables.get(k); 19238 if (tableItem instanceof ResultSet) { 19239 int resultColumnSize = ((ResultSet) tableItem).getColumns().size(); 19240 for (int x = 0; x < resultColumnSize; x++) { 19241 ResultColumn tableColumn = ((ResultSet) tableItem).getColumns().get(x); 19242 if (pivotedColumns.contains(tableColumn)) { 19243 continue; 19244 } 19245 if (tableColumn.getColumnObject() instanceof TObjectName) { 19246 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19247 relation.setEffectType(EffectType.select); 19248 relation.setTarget(new ResultColumnRelationshipElement( 19249 aliasColumnMap.get(tableColumn.getColumnObject().toString()))); 19250 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 19251 } else if (tableColumn.getColumnObject() instanceof TResultColumn) { 19252 if (((TResultColumn) tableColumn.getColumnObject()).getFieldAttr() != null) { 19253 ResultColumn targetColumn = aliasColumnMap.get( 19254 ((TResultColumn) tableColumn.getColumnObject()).getFieldAttr().toString()); 19255 if(targetColumn == null) { 19256 continue; 19257 } 19258 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19259 relation.setEffectType(EffectType.select); 19260 relation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 19261 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 19262 } else if (((TResultColumn) tableColumn.getColumnObject()).getExpr() != null) { 19263 TExpression expr = ((TResultColumn) tableColumn.getColumnObject()).getExpr(); 19264 if (expr.getExpressionType() == EExpressionType.simple_constant_t) { 19265 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19266 relation.setEffectType(EffectType.select); 19267 ResultColumn targetColumn = (ResultColumn) aliasColumnMap 19268 .getValueAtIndex(aliasColumnMap.size() - resultColumnSize + x); 19269 relation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 19270 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 19271 } 19272 } 19273 } 19274 } 19275 } else if (tableItem instanceof Table) { 19276 for (TableColumn tableColumn : ((Table) tableItem).getColumns()) { 19277 if (pivotedColumns.contains(tableColumn)) { 19278 continue; 19279 } 19280 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19281 relation.setEffectType(EffectType.select); 19282 relation.setTarget(new ResultColumnRelationshipElement( 19283 aliasColumnMap.get(tableColumn.getColumnObject().toString()))); 19284 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 19285 } 19286 } 19287 } 19288 19289 ResultSet resultSet = modelFactory.createResultSet(stmt, 19290 isTopResultSet(stmt) && isShowTopSelectResultSet()); 19291 TResultColumnList columnList = stmt.getResultColumnList(); 19292 for (int i = 0; i < columnList.size(); i++) { 19293 TResultColumn column = columnList.getResultColumn(i); 19294 ResultColumn resultColumn = modelFactory.createAndBindingSelectSetResultColumn(resultSet, column, i); 19295 if (resultColumn.getColumnObject() instanceof TResultColumn) { 19296 TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject(); 19297 if (columnObject.getFieldAttr() != null) { 19298 if ("*".equals(getColumnName(columnObject.getFieldAttr()))) { 19299 resultColumn.setShowStar(false); 19300 for (ResultColumn tableColumn : ((ResultSet) alias).getColumns()) { 19301 resultColumn.bindStarLinkColumn((TObjectName) tableColumn.getColumnObject()); 19302 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19303 relation.setEffectType(EffectType.select); 19304 relation.setTarget(new ResultColumnRelationshipElement(resultColumn, (TObjectName) tableColumn.getColumnObject())); 19305 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 19306 } 19307 } else { 19308 for (ResultColumn tableColumn : ((ResultSet) alias).getColumns()) { 19309 if (getColumnName(columnObject.getFieldAttr()) 19310 .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 19311 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19312 relation.setEffectType(EffectType.select); 19313 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 19314 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 19315 break; 19316 } 19317 } 19318 } 19319 } else if (columnObject.getExpr() != null && columnObject.getExpr() 19320 .getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) { 19321 for (ResultColumn tableColumn : ((ResultSet) alias).getColumns()) { 19322 if (getColumnName(columnObject.getExpr().getRightOperand().getObjectOperand()) 19323 .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 19324 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19325 relation.setEffectType(EffectType.select); 19326 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 19327 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 19328 break; 19329 } 19330 } 19331 } else if (columnObject.getExpr() != null && columnObject.getExpr() 19332 .getExpressionType() == EExpressionType.function_t) { 19333 Function function = (Function) createFunction(columnObject.getExpr().getFunctionCall()); 19334 for (ResultColumn arg : function.getColumns()) { 19335 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19336 relation.setEffectType(EffectType.select); 19337 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 19338 relation.addSource(new ResultColumnRelationshipElement(arg)); 19339 } 19340 } 19341 } 19342 } 19343 } else { 19344 ResultSet resultSet = modelFactory.createResultSet(stmt, isTopResultSet(stmt)); 19345 TResultColumnList columnList = stmt.getResultColumnList(); 19346 for (int i = 0; i < columnList.size(); i++) { 19347 TResultColumn column = columnList.getResultColumn(i); 19348 ResultColumn resultColumn = modelFactory.createAndBindingSelectSetResultColumn(resultSet, column, i); 19349 if (resultColumn.getColumnObject() instanceof TResultColumn) { 19350 boolean fromFunction = false; 19351 TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject(); 19352 TObjectName resultColumnFieldAttr = columnObject.getFieldAttr(); 19353 List<TObjectName> resultColumnNames = new ArrayList<TObjectName>(); 19354 if (resultColumnFieldAttr != null) { 19355 resultColumnNames.add(resultColumnFieldAttr); 19356 } else if (columnObject.getExpr() != null 19357 && column.getExpr().getExpressionType() == EExpressionType.function_t) { 19358 extractFunctionObjectNames(column.getExpr().getFunctionCall(), resultColumnNames); 19359 fromFunction = true; 19360 } 19361 19362 if (!resultColumnNames.isEmpty()) { 19363 for (TObjectName resultColumnName : resultColumnNames) { 19364 if ("*".equals(getColumnName(resultColumnName))) { 19365 resultColumn.setShowStar(false); 19366 int index = 0; 19367 for (int k = 0; k < tables.size(); k++) { 19368 Object tableItem = tables.get(k); 19369 if (tableItem instanceof ResultSet && !(tableItem instanceof QueryTable)) { 19370 for (int x = 0; x < ((ResultSet) tableItem).getColumns().size(); x++) { 19371 ResultColumn tableColumn = ((ResultSet) tableItem).getColumns().get(x); 19372 if (pivotedColumns.contains(tableColumn)) { 19373 continue; 19374 } 19375 if (tableColumn.getColumnObject() instanceof TObjectName) { 19376 resultColumn.bindStarLinkColumn( 19377 (TObjectName) tableColumn.getColumnObject()); 19378 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19379 relation.setEffectType(EffectType.select); 19380 relation.setTarget(new ResultColumnRelationshipElement(resultColumn, (TObjectName) tableColumn.getColumnObject())); 19381 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 19382 } else if (tableColumn.getColumnObject() instanceof TResultColumn) { 19383 if (((TResultColumn) tableColumn.getColumnObject()) 19384 .getFieldAttr() != null) { 19385 if (tableColumn.hasStarLinkColumn()) { 19386 for (int z = 0; z < tableColumn.getStarLinkColumnList() 19387 .size(); z++) { 19388 ResultColumn resultColumn1 = modelFactory 19389 .createResultColumn((ResultSet) tableItem, 19390 tableColumn.getStarLinkColumnList().get(z)); 19391 DataFlowRelationship relation = modelFactory 19392 .createDataFlowRelation(); 19393 relation.setEffectType(EffectType.select); 19394 relation.setTarget( 19395 new ResultColumnRelationshipElement(resultColumn)); 19396 relation.addSource( 19397 new ResultColumnRelationshipElement(resultColumn1)); 19398 tableColumn.getStarLinkColumns().remove(getColumnName( 19399 tableColumn.getStarLinkColumnList().get(z))); 19400 z--; 19401 } 19402 } else { 19403 resultColumn.bindStarLinkColumn( 19404 ((TResultColumn) tableColumn.getColumnObject()) 19405 .getFieldAttr()); 19406 DataFlowRelationship relation = modelFactory 19407 .createDataFlowRelation(); 19408 relation.setEffectType(EffectType.select); 19409 relation.setTarget( 19410 new ResultColumnRelationshipElement(resultColumn, ((TResultColumn) tableColumn.getColumnObject()) 19411 .getFieldAttr())); 19412 relation.addSource( 19413 new ResultColumnRelationshipElement(tableColumn)); 19414 } 19415 } else if (((TResultColumn) tableColumn.getColumnObject()) 19416 .getExpr() != null) { 19417 TExpression expr = ((TResultColumn) tableColumn.getColumnObject()) 19418 .getExpr(); 19419 if (expr.getExpressionType() == EExpressionType.simple_constant_t) { 19420 TObjectName columnName = new TObjectName(); 19421 columnName.setString(expr.toString()); 19422 resultColumn.bindStarLinkColumn(columnName); 19423 DataFlowRelationship relation = modelFactory 19424 .createDataFlowRelation(); 19425 relation.setEffectType(EffectType.select); 19426 relation.setTarget( 19427 new ResultColumnRelationshipElement(resultColumn, columnName)); 19428 relation.addSource( 19429 new ResultColumnRelationshipElement(tableColumn)); 19430 } 19431 } 19432 } 19433 } 19434 } else if (tableItem instanceof Table) { 19435 for (TableColumn tableColumn : ((Table) tableItem).getColumns()) { 19436 if (pivotedColumns.contains(tableColumn)) { 19437 continue; 19438 } 19439 resultColumn.bindStarLinkColumn((TObjectName) tableColumn.getColumnObject(), 19440 index); 19441 index++; 19442 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19443 relation.setEffectType(EffectType.select); 19444 relation.setTarget(new ResultColumnRelationshipElement(resultColumn, (TObjectName) tableColumn.getColumnObject())); 19445 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 19446 } 19447 } else if (tableItem instanceof QueryTable) { 19448 for (ResultColumn tableColumn : ((QueryTable) tableItem).getColumns()) { 19449 if (pivotedColumns.contains(tableColumn)) { 19450 continue; 19451 } 19452 TObjectName column1 = new TObjectName(); 19453 column1.setString(tableColumn.getName()); 19454 resultColumn.bindStarLinkColumn(column1, index); 19455 index++; 19456 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19457 relation.setEffectType(EffectType.select); 19458 relation.setTarget(new ResultColumnRelationshipElement(resultColumn, column1)); 19459 relation.addSource(new ResultColumnRelationshipElement(tableColumn), false); 19460 } 19461 } 19462 } 19463 } else { 19464 ResultColumn pivotedTableColumn = getPivotedTableColumn(pivotedTable, resultColumnName); 19465 if (pivotedTableColumn != null) { 19466 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19467 relation.setEffectType(EffectType.select); 19468 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 19469 relation.addSource(new ResultColumnRelationshipElement(pivotedTableColumn)); 19470 } else { 19471 for (int k = 0; k < tables.size(); k++) { 19472 Object tableItem = tables.get(k); 19473 if (tableItem instanceof ResultSet) { 19474 for (ResultColumn tableColumn : ((ResultSet) tableItem).getColumns()) { 19475 if (DlineageUtil 19476 .getIdentifierNormalColumnName(tableColumn.getName()).equals(getColumnName(resultColumnName))) { 19477 if (fromFunction) { 19478 Function function = (Function)createPivotedFunction(column.getExpr().getFunctionCall(), tableColumn); 19479 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19480 relation.setEffectType(EffectType.select); 19481 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 19482 if (function.getColumns() != null && !function.getColumns().isEmpty()) { 19483 for (ResultColumn functionColumn : function.getColumns()) { 19484 relation.addSource(new ResultColumnRelationshipElement(functionColumn)); 19485 } 19486 } 19487 } else { 19488 DataFlowRelationship relation = modelFactory 19489 .createDataFlowRelation(); 19490 relation.setEffectType(EffectType.select); 19491 relation.setTarget( 19492 new ResultColumnRelationshipElement(resultColumn)); 19493 relation.addSource( 19494 new ResultColumnRelationshipElement(tableColumn)); 19495 } 19496 break; 19497 } 19498 } 19499 } else if (tableItem instanceof Table) { 19500 for (TableColumn tableColumn : ((Table) tableItem).getColumns()) { 19501 if (getColumnName(resultColumnName).equals(DlineageUtil 19502 .getIdentifierNormalColumnName(tableColumn.getName()))) { 19503 DataFlowRelationship relation = modelFactory 19504 .createDataFlowRelation(); 19505 relation.setEffectType(EffectType.select); 19506 relation.setTarget( 19507 new ResultColumnRelationshipElement(resultColumn)); 19508 relation.addSource( 19509 new TableColumnRelationshipElement(tableColumn)); 19510 break; 19511 } 19512 } 19513 } 19514 } 19515 } 19516 } 19517 } 19518 } else if (columnObject.getExpr() != null && columnObject.getExpr() 19519 .getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) { 19520 for (int k = 0; k < tables.size(); k++) { 19521 Object tableItem = tables.get(k); 19522 if (tableItem instanceof ResultSet) { 19523 for (ResultColumn tableColumn : ((ResultSet) tableItem).getColumns()) { 19524 if (columnObject.getExpr().getRightOperand().getObjectOperand() != null 19525 && getColumnName( 19526 columnObject.getExpr().getRightOperand().getObjectOperand()) 19527 .equals(DlineageUtil.getIdentifierNormalColumnName( 19528 tableColumn.getName()))) { 19529 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19530 relation.setEffectType(EffectType.select); 19531 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 19532 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 19533 break; 19534 } else if (columnObject.getExpr().getRightOperand() 19535 .getExpressionType() == EExpressionType.function_t) { 19536 List<TExpression> expressions = new ArrayList<TExpression>(); 19537 getFunctionExpressions(expressions, new ArrayList<TExpression>(), 19538 columnObject.getExpr().getRightOperand().getFunctionCall()); 19539 for (int j = 0; j < expressions.size(); j++) { 19540 columnsInExpr visitor = new columnsInExpr(); 19541 expressions.get(j).inOrderTraverse(visitor); 19542 List<TObjectName> objectNames = visitor.getObjectNames(); 19543 if (objectNames == null) { 19544 continue; 19545 } 19546 for (TObjectName columnName : objectNames) { 19547 if (getColumnName(columnName).equals(DlineageUtil 19548 .getIdentifierNormalColumnName(tableColumn.getName()))) { 19549 DataFlowRelationship relation = modelFactory 19550 .createDataFlowRelation(); 19551 relation.setEffectType(EffectType.select); 19552 relation.setTarget( 19553 new ResultColumnRelationshipElement(resultColumn)); 19554 relation.addSource( 19555 new ResultColumnRelationshipElement(tableColumn)); 19556 break; 19557 } 19558 } 19559 } 19560 } 19561 } 19562 } else if (tableItem instanceof Table) { 19563 for (TableColumn tableColumn : ((Table) tableItem).getColumns()) { 19564 if (getColumnName(columnObject.getExpr().getRightOperand().getObjectOperand()) 19565 .equals(DlineageUtil 19566 .getIdentifierNormalColumnName(tableColumn.getName()))) { 19567 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19568 relation.setEffectType(EffectType.select); 19569 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 19570 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 19571 break; 19572 } 19573 } 19574 } 19575 } 19576 } 19577 } 19578 } 19579 } 19580 19581 analyzeSelectIntoClause(stmt); 19582 } 19583 19584 private Function createPivotedFunction(TFunctionCall functionCall, ResultColumn sourceColumn) { 19585 Function function = modelFactory.createFunction((TFunctionCall) functionCall); 19586 ResultColumn column = modelFactory.createFunctionResultColumn(function, 19587 ((TFunctionCall) functionCall).getFunctionName()); 19588 if ("COUNT".equalsIgnoreCase(((TFunctionCall) functionCall).getFunctionName().toString())) { 19589 // @see https://e.gitee.com/gudusoft/issues/list?issue=I40NUP 19590 // COUNT特殊处理,不和参数关联 19591 if (option.isShowCountTableColumn()) { 19592 analyzePivotedFunctionArgumentsDataFlowRelation(column, functionCall, sourceColumn); 19593 } 19594 } else { 19595 analyzePivotedFunctionArgumentsDataFlowRelation(column, functionCall, sourceColumn); 19596 Set<Object> functionTableModelObjs = modelManager.getFunctionTable(getIdentifiedFunctionName(function)); 19597 if (functionTableModelObjs!=null && functionTableModelObjs.iterator().next() instanceof ResultSet) { 19598 ResultSet functionTableModel = (ResultSet) functionTableModelObjs.iterator().next(); 19599 if (functionTableModel.getColumns() != null) { 19600 for (int j = 0; j < functionTableModel.getColumns().size(); j++) { 19601 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19602 relation.setEffectType(EffectType.select); 19603 relation.setTarget(new ResultColumnRelationshipElement(column)); 19604 relation.addSource(new ResultColumnRelationshipElement( 19605 functionTableModel.getColumns().get(j))); 19606 } 19607 } 19608 } 19609 } 19610 return function; 19611 } 19612 19613 private void analyzePivotedFunctionArgumentsDataFlowRelation(ResultColumn column, TFunctionCall functionCall, 19614 ResultColumn sourceColumn) { 19615 List<TExpression> directExpressions = new ArrayList<TExpression>(); 19616 List<TExpression> indirectExpressions = new ArrayList<TExpression>(); 19617 19618 getFunctionExpressions(directExpressions, indirectExpressions, functionCall); 19619 19620 for (int j = 0; j < directExpressions.size(); j++) { 19621 columnsInExpr visitor = new columnsInExpr(); 19622 directExpressions.get(j).inOrderTraverse(visitor); 19623 19624 List<TObjectName> objectNames = visitor.getObjectNames(); 19625 List<TParseTreeNode> constants = visitor.getConstants(); 19626 19627 if (objectNames != null) { 19628 for (TObjectName name : objectNames) { 19629 if (DlineageUtil.compareColumnIdentifier(name.toString(), sourceColumn.getName())) { 19630 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19631 relation.setEffectType(EffectType.select); 19632 relation.setTarget(new ResultColumnRelationshipElement(column)); 19633 relation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 19634 } 19635 } 19636 } 19637 if (constants != null) { 19638 for (TParseTreeNode name : constants) { 19639 if (name.toString().equals(sourceColumn.getName())) { 19640 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19641 relation.setEffectType(EffectType.select); 19642 relation.setTarget(new ResultColumnRelationshipElement(column)); 19643 relation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 19644 } 19645 } 19646 } 19647 } 19648 } 19649 19650 private void extractFunctionObjectNames(TFunctionCall functionCall, List<TObjectName> resultColumnNames) { 19651 List<TExpression> directExpressions = new ArrayList<TExpression>(); 19652 List<TExpression> indirectExpressions = new ArrayList<TExpression>(); 19653 19654 getFunctionExpressions(directExpressions, indirectExpressions, functionCall); 19655 19656 for (int j = 0; j < directExpressions.size(); j++) { 19657 columnsInExpr visitor = new columnsInExpr(); 19658 directExpressions.get(j).inOrderTraverse(visitor); 19659 19660 List<TObjectName> objectNames = visitor.getObjectNames(); 19661 List<TParseTreeNode> functions = visitor.getFunctions(); 19662 List<TParseTreeNode> constants = visitor.getConstants(); 19663 19664 if (objectNames != null) { 19665 resultColumnNames.addAll(objectNames); 19666 } 19667 19668 if (constants != null) { 19669 for(TParseTreeNode item: constants) { 19670 if(item instanceof TConstant && ((TConstant) item).getLiteralType().getText().equals(ELiteralType.string_et.getText())) { 19671 TObjectName object = new TObjectName(); 19672 object.setString(item.toString()); 19673 resultColumnNames.add(object); 19674 } 19675 } 19676 } 19677 19678 if (functions != null && !functions.isEmpty()) { 19679 for (TParseTreeNode function : functions) { 19680 if (function instanceof TFunctionCall) { 19681 extractFunctionObjectNames((TFunctionCall) function, resultColumnNames); 19682 } 19683 } 19684 } 19685 } 19686 } 19687 19688 private String getResultColumnString(TResultColumn resultColumn) { 19689 if (resultColumn.getAliasClause() != null) { 19690 return resultColumn.getAliasClause().toString(); 19691 } 19692 return resultColumn.toString(); 19693 } 19694 19695 private void analyzeBigQueryUnnest(TSelectSqlStatement stmt, TTable table) { 19696 Table unnestTable = modelFactory.createTableFromCreateDDL(table, false, getTempTableName(table)); 19697 unnestTable.setSubType(SubType.unnest); 19698 TUnnestClause clause = table.getUnnestClause(); 19699 TExpression arrayExpr = clause.getArrayExpr(); 19700 if (arrayExpr == null){ 19701 if (clause.getColumns() != null) { 19702 for (TObjectName column : clause.getColumns()) { 19703 if (clause.getDerivedColumnList() != null) { 19704 unnestTable.setCreateTable(true); 19705 for (int i = 0; i < clause.getDerivedColumnList().size(); i++) { 19706 TObjectName columnName = new TObjectName(); 19707 columnName.setString(column.getColumnNameOnly() + "." 19708 + clause.getDerivedColumnList().getObjectName(i).getColumnNameOnly()); 19709 TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, columnName, true); 19710 List<TObjectName> columns = new ArrayList<TObjectName>(); 19711 columns.add(column); 19712 analyzeDataFlowRelation(tableColumn, columns, EffectType.select, null); 19713 } 19714 } 19715 else { 19716 unnestTable.setCreateTable(true); 19717 boolean find = false; 19718 if (column.getSourceTable() != null && modelManager.getModel(column.getSourceTable()) instanceof Table) { 19719 Table sourceTable = (Table)modelManager.getModel(column.getSourceTable()); 19720 if(sourceTable!=null) { 19721 for(TableColumn tableColumn: sourceTable.getColumns()) { 19722 if(tableColumn.isStruct()) { 19723 List<String> names = SQLUtil.parseNames(tableColumn.getName()); 19724 if (names.get(0).equalsIgnoreCase(column.getColumnNameOnly())) { 19725 TObjectName columnName = new TObjectName(); 19726 columnName.setString(tableColumn.getName()); 19727 TableColumn unnestTableColumn = modelFactory.createTableColumn(unnestTable, 19728 columnName, true); 19729 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19730 relation.setEffectType(EffectType.select); 19731 relation.setTarget(new TableColumnRelationshipElement(unnestTableColumn)); 19732 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 19733 find = true; 19734 } 19735 } 19736 } 19737 } 19738 } 19739 if (!find) { 19740 TObjectName colName = column; 19741 if (table.getAliasClause() != null && table.getAliasClause().getAliasName() != null) { 19742 colName = table.getAliasClause().getAliasName(); 19743 } 19744 TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, colName, true); 19745 List<TObjectName> columns = new ArrayList<TObjectName>(); 19746 columns.add(column); 19747 analyzeDataFlowRelation(tableColumn, columns, EffectType.select, null); 19748 } 19749 } 19750 } 19751 } 19752 return; 19753 } 19754 List<TExpression> expressions = new ArrayList<TExpression>(); 19755 TExpressionList values = arrayExpr.getExprList(); 19756 if (values == null) { 19757 expressions.add(arrayExpr); 19758 } 19759 else { 19760 for(TExpression value: values) { 19761 expressions.add(value); 19762 } 19763 } 19764 for (TExpression value : expressions) { 19765 unnestTable.setCreateTable(true); 19766 if (value.getExpressionType() == EExpressionType.simple_object_name_t) { 19767 if (table.getAliasClause() != null) { 19768 TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, 19769 table.getAliasClause().getAliasName(), true); 19770 columnsInExpr visitor = new columnsInExpr(); 19771 value.inOrderTraverse(visitor); 19772 List<TObjectName> columns = visitor.getObjectNames(); 19773 analyzeDataFlowRelation(tableColumn, columns, EffectType.select, null); 19774 } else { 19775 TResultColumnList resultColumnList = stmt.getResultColumnList(); 19776 for (int i = 0; i < resultColumnList.size(); i++) { 19777 TObjectName firstColumn = new TObjectName(); 19778 firstColumn.setString(resultColumnList.getResultColumn(0).getColumnNameOnly()); 19779 TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, firstColumn, true); 19780 columnsInExpr visitor = new columnsInExpr(); 19781 value.inOrderTraverse(visitor); 19782 List<TObjectName> columns = visitor.getObjectNames(); 19783 analyzeDataFlowRelation(tableColumn, columns, EffectType.select, null); 19784 } 19785 } 19786 } else if (value.getExpressionType() == EExpressionType.function_t) { 19787 if (table.getAliasClause() != null) { 19788 TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, 19789 table.getAliasClause().getAliasName(), true); 19790 columnsInExpr visitor = new columnsInExpr(); 19791 value.inOrderTraverse(visitor); 19792 List<TParseTreeNode> functions = visitor.getFunctions(); 19793 analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.select, null); 19794 } else { 19795 TResultColumnList resultColumnList = stmt.getResultColumnList(); 19796 for (int i = 0; i < resultColumnList.size(); i++) { 19797 TObjectName firstColumn = new TObjectName(); 19798 firstColumn.setString(resultColumnList.getResultColumn(0).getColumnNameOnly()); 19799 TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, firstColumn, true); 19800 columnsInExpr visitor = new columnsInExpr(); 19801 value.inOrderTraverse(visitor); 19802 List<TObjectName> columns = visitor.getObjectNames(); 19803 analyzeDataFlowRelation(tableColumn, columns, EffectType.select, null); 19804 } 19805 } 19806 } else if (value.getExpressionType() == EExpressionType.simple_constant_t) { 19807 if (table.getAliasClause() != null) { 19808 TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, 19809 table.getAliasClause().getAliasName(), true); 19810 columnsInExpr visitor = new columnsInExpr(); 19811 value.inOrderTraverse(visitor); 19812 List<TParseTreeNode> constants = visitor.getConstants(); 19813 analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, null); 19814 } else { 19815 TObjectName firstColumn = new TObjectName(); 19816 firstColumn.setString("f0_"); 19817 TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, firstColumn, true); 19818 columnsInExpr visitor = new columnsInExpr(); 19819 value.inOrderTraverse(visitor); 19820 List<TParseTreeNode> constants = visitor.getConstants(); 19821 analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, null); 19822 } 19823 } else if (value.getExpressionType() == EExpressionType.list_t) { 19824 if (arrayExpr.getTypeName() != null && arrayExpr.getTypeName().getColumnDefList() != null) { 19825 for (int i = 0; i < arrayExpr.getTypeName().getColumnDefList().size(); i++) { 19826 TColumnDefinition column = arrayExpr.getTypeName().getColumnDefList().getColumn(i); 19827 if (column != null && column.getColumnName() != null) { 19828 TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, 19829 column.getColumnName(), true); 19830 columnsInExpr visitor = new columnsInExpr(); 19831 value.getExprList().getExpression(i).inOrderTraverse(visitor); 19832 List<TParseTreeNode> constants = visitor.getConstants(); 19833 analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, null); 19834 } 19835 } 19836 } else { 19837 for (int i = 0; i < value.getExprList().size(); i++) { 19838 TObjectName firstColumn = new TObjectName(); 19839 firstColumn.setString("f" + i + "_"); 19840 TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, firstColumn, true); 19841 columnsInExpr visitor = new columnsInExpr(); 19842 value.getExprList().getExpression(i).inOrderTraverse(visitor); 19843 List<TParseTreeNode> constants = visitor.getConstants(); 19844 analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, null); 19845 } 19846 } 19847 } else if (value.getExpressionType() == EExpressionType.subquery_t) { 19848 analyzeSelectStmt(value.getSubQuery()); 19849 ResultSet resultSet = (ResultSet) modelManager.getModel(value.getSubQuery()); 19850 if (resultSet != null) { 19851 for (int i = 0; i < resultSet.getColumns().size(); i++) { 19852 TObjectName columnName = new TObjectName(); 19853 if(resultSet.getColumns().get(i).getAlias()!=null) { 19854 columnName.setString(resultSet.getColumns().get(i).getAlias()); 19855 } 19856 else { 19857 columnName.setString(getColumnName(resultSet.getColumns().get(i).getName())); 19858 } 19859 TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, columnName, true); 19860 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19861 relation.setEffectType(EffectType.select); 19862 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 19863 relation.addSource( 19864 new ResultColumnRelationshipElement(resultSet.getColumns().get(i))); 19865 } 19866 } 19867 } 19868 } 19869 } 19870 19871 private void analyzePrestoUnnest(TSelectSqlStatement stmt, TTable table) { 19872 List<Table> tables = new ArrayList<Table>(); 19873 TTable targetTable = stmt.getTables().getTable(0); 19874 Table stmtTable = modelFactory.createTable(targetTable); 19875 Object sourceTable = null; 19876 if (targetTable.getSubquery() != null) { 19877 analyzeSelectStmt(targetTable.getSubquery()); 19878 if (targetTable.getSubquery().isCombinedQuery()) { 19879 ResultSet sourceResultSet = (ResultSet) modelManager.getModel(targetTable.getSubquery()); 19880 sourceTable = sourceResultSet; 19881 } else if (targetTable.getSubquery().getResultColumnList() != null) { 19882 ResultSet sourceResultSet = (ResultSet) modelManager 19883 .getModel(targetTable.getSubquery().getResultColumnList()); 19884 sourceTable = sourceResultSet; 19885 } else if (targetTable.getSubquery().getValueClause() != null) { 19886 List<TResultColumnList> rowList = targetTable.getSubquery().getValueClause().getRows(); 19887 if (rowList != null && rowList.size() > 0) { 19888 Table valuesTable = modelFactory.createTableByName("Values-Table", true); 19889 int columnCount = rowList.get(0).size(); 19890 for (int j = 1; j <= columnCount; j++) { 19891 TObjectName columnName = new TObjectName(); 19892 TResultColumn columnObject = rowList.get(0).getResultColumn(j - 1); 19893 if (columnObject.getExpr().getExpressionType() == EExpressionType.typecast_t) { 19894 columnName.setString(columnObject.getExpr().getLeftOperand().toString()); 19895 } else { 19896 columnName.setString(columnObject.getExpr().toString()); 19897 } 19898 modelFactory.createTableColumn(valuesTable, columnName, true); 19899 } 19900 valuesTable.setCreateTable(true); 19901 valuesTable.setSubType(SubType.values_table); 19902 sourceTable = valuesTable; 19903 } 19904 } 19905 } 19906 tables.add(stmtTable); 19907 Table unnestTable = modelFactory.createTable(table); 19908 unnestTable.setSubType(SubType.unnest); 19909 tables.add(unnestTable); 19910 if (table.getAliasClause() != null && table.getAliasClause().getColumns() != null 19911 && table.getUnnestClause().getColumns() != null) { 19912 int unnestTableSize = table.getUnnestClause().getColumns().size(); 19913 for (int i = 0; i < table.getAliasClause().getColumns().size(); i++) { 19914 TableColumn sourceColumn = null; 19915 if (unnestTableSize > i) { 19916 sourceColumn = modelFactory.createTableColumn(stmtTable, 19917 table.getUnnestClause().getColumns().getObjectName(i), true); 19918 if (sourceTable instanceof Table) { 19919 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19920 relation.setEffectType(EffectType.select); 19921 relation.setTarget(new TableColumnRelationshipElement(sourceColumn)); 19922 relation.addSource( 19923 new TableColumnRelationshipElement(((Table) sourceTable).getColumns().get(i))); 19924 } else if (sourceTable instanceof ResultSet) { 19925 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19926 relation.setEffectType(EffectType.select); 19927 relation.setTarget(new TableColumnRelationshipElement(sourceColumn)); 19928 relation.addSource( 19929 new ResultColumnRelationshipElement(((ResultSet) sourceTable).getColumns().get(i))); 19930 } 19931 } else { 19932 sourceColumn = modelFactory.createTableColumn(stmtTable, 19933 table.getUnnestClause().getColumns().getObjectName(unnestTableSize - 1), true); 19934 } 19935 TableColumn targetColumn = modelFactory.createTableColumn(unnestTable, 19936 table.getAliasClause().getColumns().getObjectName(i), true); 19937 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19938 relation.setEffectType(EffectType.select); 19939 relation.setTarget(new TableColumnRelationshipElement(targetColumn)); 19940 relation.addSource(new TableColumnRelationshipElement(sourceColumn)); 19941 } 19942 } 19943 19944 ResultSet resultSet = modelFactory.createResultSet(stmt, 19945 isTopResultSet(stmt) && isShowTopSelectResultSet()); 19946 TResultColumnList columnList = stmt.getResultColumnList(); 19947 for (int i = 0; i < columnList.size(); i++) { 19948 TResultColumn column = columnList.getResultColumn(i); 19949 ResultColumn resultColumn = modelFactory.createSelectSetResultColumn(resultSet, column, i); 19950 if (resultColumn.getColumnObject() instanceof TResultColumn) { 19951 TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject(); 19952 if (columnObject.getFieldAttr() != null) { 19953 if ("*".equals(getColumnName(columnObject.getFieldAttr()))) { 19954 for (int k = 0; k < tables.size(); k++) { 19955 Table tableItem = tables.get(k); 19956 for (TableColumn tableColumn : tableItem.getColumns()) { 19957 resultColumn.bindStarLinkColumn(tableColumn.getColumnObject()); 19958 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19959 relation.setEffectType(EffectType.select); 19960 relation.setTarget(new ResultColumnRelationshipElement(resultColumn, tableColumn.getColumnObject())); 19961 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 19962 } 19963 } 19964 } else { 19965 boolean match = false; 19966 for (int k = 0; k < tables.size(); k++) { 19967 Table tableItem = tables.get(k); 19968 for (TableColumn tableColumn : tableItem.getColumns()) { 19969 if (getColumnName(columnObject.getFieldAttr()) 19970 .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 19971 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19972 relation.setEffectType(EffectType.select); 19973 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 19974 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 19975 match = true; 19976 } 19977 } 19978 } 19979 if (!match) { 19980 TableColumn tableColumn = modelFactory.createTableColumn(stmtTable, 19981 columnObject.getFieldAttr(), false); 19982 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 19983 relation.setEffectType(EffectType.select); 19984 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 19985 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 19986 } 19987 } 19988 } 19989 } 19990 } 19991 } 19992 19993 private void analyzeLateralView(TSelectSqlStatement stmt, TTable table, ArrayList<TLateralView> lateralViews) { 19994 List<Object> tables = new ArrayList<Object>(); 19995 Object stmtTable = null; 19996 if(table.getSubquery()!=null) { 19997 stmtTable = modelFactory.createQueryTable(table); 19998 tables.add(stmtTable); 19999 } 20000 else { 20001 stmtTable = modelFactory.createTable(table); 20002 tables.add(stmtTable); 20003 } 20004 for (int i = 0; i < lateralViews.size(); i++) { 20005 TLateralView lateralView = lateralViews.get(i); 20006 TFunctionCall functionCall = lateralView.getUdtf(); 20007 List<TExpression> expressions = new ArrayList<TExpression>(); 20008 if (functionCall == null) { 20009 continue; 20010 } 20011 Function function = modelFactory.createFunction(functionCall); 20012 ResultColumn column = modelFactory.createFunctionResultColumn(function, 20013 ((TFunctionCall) functionCall).getFunctionName()); 20014 20015 Table lateralTable = null; 20016 if (lateralView.getTableAlias() != null) { 20017 lateralTable = modelFactory.createTableByName(lateralView.getTableAlias().getAliasName(), true); 20018 } else { 20019 lateralTable = modelFactory.createTableByName(functionCall.toString(), true); 20020 } 20021 20022 for (int j = 0; j < lateralView.getColumnAliasList().size(); j++) { 20023 TObjectName viewColumn = lateralView.getColumnAliasList().getObjectName(j); 20024 TableColumn tableColumn = modelFactory.createTableColumn(lateralTable, viewColumn, true); 20025 20026 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 20027 relation.setEffectType(EffectType.select); 20028 relation.setTarget(new TableColumnRelationshipElement(tableColumn)); 20029 relation.addSource(new ResultColumnRelationshipElement(column)); 20030 } 20031 20032 getFunctionExpressions(expressions, new ArrayList<TExpression>(), functionCall); 20033 for (int j = 0; j < expressions.size(); j++) { 20034 columnsInExpr visitor = new columnsInExpr(); 20035 expressions.get(j).inOrderTraverse(visitor); 20036 List<TObjectName> objectNames = visitor.getObjectNames(); 20037 if (objectNames == null) { 20038 continue; 20039 } 20040 for (TObjectName columnName : objectNames) { 20041 boolean match = false; 20042 for (int k = 0; k < tables.size(); k++) { 20043 Object item = tables.get(k); 20044 if(item instanceof Table) { 20045 Table tableItem = (Table)item; 20046 for (TableColumn tableColumn : tableItem.getColumns()) { 20047 if (getColumnName(columnName) 20048 .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 20049 match = true; 20050 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 20051 relation.setEffectType(EffectType.select); 20052 relation.setTarget(new ResultColumnRelationshipElement(column)); 20053 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 20054 } 20055 } 20056 } 20057 else { 20058 ResultSet tableItem = (ResultSet)item; 20059 for (ResultColumn tableColumn : tableItem.getColumns()) { 20060 if (getColumnName(columnName) 20061 .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 20062 match = true; 20063 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 20064 relation.setEffectType(EffectType.select); 20065 relation.setTarget(new ResultColumnRelationshipElement(column)); 20066 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 20067 } 20068 } 20069 } 20070 } 20071 if (!match) { 20072 if(stmtTable instanceof Table) { 20073 TableColumn tableColumn = modelFactory.createTableColumn((Table)stmtTable, columnName, false); 20074 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 20075 relation.setEffectType(EffectType.select); 20076 relation.setTarget(new ResultColumnRelationshipElement(column)); 20077 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 20078 } 20079 else { 20080 ResultColumn tableColumn = modelFactory.createResultColumn((ResultSet)stmtTable, columnName, false); 20081 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 20082 relation.setEffectType(EffectType.select); 20083 relation.setTarget(new ResultColumnRelationshipElement(column)); 20084 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 20085 } 20086 } 20087 } 20088 List<TParseTreeNode> constants = visitor.getConstants(); 20089 if (!constants.isEmpty()) { 20090 if (option.isShowConstantTable()) { 20091 Table constantTable = modelFactory.createConstantsTable(stmtStack.peek()); 20092 for (TParseTreeNode constant : constants) { 20093 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 20094 relation.setEffectType(EffectType.select); 20095 relation.setTarget(new ResultColumnRelationshipElement(column)); 20096 if (constant instanceof TConstant) { 20097 TableColumn constantColumn = modelFactory.createTableColumn(constantTable, 20098 (TConstant) constant); 20099 relation.addSource(new ConstantRelationshipElement(constantColumn)); 20100 } else if (constant instanceof TObjectName) { 20101 TableColumn constantColumn = modelFactory.createTableColumn(constantTable, 20102 (TObjectName) constant, false); 20103 relation.addSource(new ConstantRelationshipElement(constantColumn)); 20104 } 20105 } 20106 } 20107 } 20108 20109 List<TParseTreeNode> functions = visitor.getFunctions(); 20110 if (functions != null && !functions.isEmpty()) { 20111 analyzeFunctionDataFlowRelation(column, functions, EffectType.function); 20112 } 20113 } 20114 tables.add(lateralTable); 20115 } 20116 20117 ResultSet resultSet = modelFactory.createResultSet(stmt, 20118 isTopResultSet(stmt) && isShowTopSelectResultSet()); 20119 TResultColumnList columnList = stmt.getResultColumnList(); 20120 for (int i = 0; i < columnList.size(); i++) { 20121 TResultColumn column = columnList.getResultColumn(i); 20122 ResultColumn resultColumn = modelFactory.createSelectSetResultColumn(resultSet, column, i); 20123 if (resultColumn.getColumnObject() instanceof TResultColumn) { 20124 TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject(); 20125 if (columnObject.getFieldAttr() != null) { 20126 if ("*".equals(getColumnName(columnObject.getFieldAttr()))) { 20127 for (int k = 0; k < tables.size(); k++) { 20128 Object item = tables.get(k); 20129 if(item instanceof Table) { 20130 Table tableItem = (Table)item; 20131 for (TableColumn tableColumn : tableItem.getColumns()) { 20132 resultColumn.bindStarLinkColumn(tableColumn.getColumnObject()); 20133 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 20134 relation.setEffectType(EffectType.select); 20135 relation.setTarget(new ResultColumnRelationshipElement(resultColumn, tableColumn.getColumnObject())); 20136 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 20137 } 20138 } 20139 else { 20140 ResultSet tableItem = (ResultSet)item; 20141 for (ResultColumn tableColumn : tableItem.getColumns()) { 20142 TObjectName linkColumn = new TObjectName(); 20143 linkColumn.setString(tableColumn.getName()); 20144 resultColumn.bindStarLinkColumn(linkColumn); 20145 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 20146 relation.setEffectType(EffectType.select); 20147 relation.setTarget(new ResultColumnRelationshipElement(resultColumn, linkColumn)); 20148 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 20149 } 20150 } 20151 } 20152 } else { 20153 boolean match = false; 20154 for (int k = 0; k < tables.size(); k++) { 20155 Object item = tables.get(k); 20156 if(item instanceof Table) { 20157 Table tableItem = (Table)item; 20158 for (TableColumn tableColumn : tableItem.getColumns()) { 20159 if (getColumnName(columnObject.getFieldAttr()) 20160 .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 20161 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 20162 relation.setEffectType(EffectType.select); 20163 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 20164 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 20165 match = true; 20166 } 20167 } 20168 } 20169 else { 20170 ResultSet tableItem = (ResultSet)item; 20171 for (ResultColumn tableColumn : tableItem.getColumns()) { 20172 if (getColumnName(columnObject.getFieldAttr()) 20173 .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 20174 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 20175 relation.setEffectType(EffectType.select); 20176 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 20177 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 20178 match = true; 20179 } 20180 } 20181 } 20182 } 20183 if (!match) { 20184 if(stmtTable instanceof Table) { 20185 TableColumn tableColumn = modelFactory.createTableColumn((Table)stmtTable, 20186 columnObject.getFieldAttr(), false); 20187 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 20188 relation.setEffectType(EffectType.select); 20189 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 20190 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 20191 } 20192 else { 20193 ResultColumn tableColumn = modelFactory.createResultColumn((ResultSet)stmtTable, 20194 columnObject.getFieldAttr(), false); 20195 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 20196 relation.setEffectType(EffectType.select); 20197 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 20198 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 20199 } 20200 } 20201 } 20202 } 20203 else if (columnObject.getExpr() != null 20204 && columnObject.getExpr().getExpressionType() == EExpressionType.function_t) { 20205 analyzeResultColumn(column, EffectType.select); 20206 for (int k = 0; k < tables.size(); k++) { 20207 Object item = tables.get(k); 20208 if (item instanceof Table) { 20209 Table tableItem = (Table) item; 20210 for (TableColumn tableColumn : tableItem.getColumns()) { 20211 if (getColumnName(resultColumn.getName()).equals( 20212 DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 20213 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 20214 relation.setEffectType(EffectType.select); 20215 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 20216 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 20217 } 20218 } 20219 } else { 20220 ResultSet tableItem = (ResultSet) item; 20221 for (ResultColumn tableColumn : tableItem.getColumns()) { 20222 if (getColumnName(resultColumn.getName()).equals( 20223 DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) { 20224 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 20225 relation.setEffectType(EffectType.select); 20226 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 20227 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 20228 } 20229 } 20230 } 20231 } 20232 } 20233 } 20234 } 20235 } 20236 20237 private boolean isFromFunction(TObjectName object) { 20238 20239 Stack<TParseTreeNode> nodes = object.getStartToken().getNodesStartFromThisToken(); 20240 if (nodes != null) { 20241 for (int i = 0; i < nodes.size(); i++) { 20242 if (nodes.get(i) instanceof TFunctionCall) { 20243 return true; 20244 } 20245 } 20246 } 20247 return false; 20248 } 20249 20250 private TResultColumnList getResultColumnList(TSelectSqlStatement stmt) { 20251 // Iterative DFS (left-first) to find the first non-combined query's result column list. 20252 // Avoids StackOverflow with deeply nested UNION trees. 20253 Deque<TSelectSqlStatement> stack = new ArrayDeque<>(); 20254 stack.push(stmt); 20255 while (!stack.isEmpty()) { 20256 TSelectSqlStatement current = stack.pop(); 20257 if (current.isCombinedQuery()) { 20258 // Push right first so left is processed first (stack is LIFO) 20259 if (current.getRightStmt() != null) stack.push(current.getRightStmt()); 20260 if (current.getLeftStmt() != null) stack.push(current.getLeftStmt()); 20261 } else { 20262 if (current.getResultColumnList() != null) { 20263 return current.getResultColumnList(); 20264 } 20265 } 20266 } 20267 return null; 20268 } 20269 20270 private void createPseudoImpactRelation(TCustomSqlStatement stmt, ResultSet resultSetModel, EffectType effectType) { 20271 if (stmt.getTables() != null) { 20272 for (int i = 0; i < stmt.getTables().size(); i++) { 20273 TTable table = stmt.getTables().getTable(i); 20274 if (modelManager.getModel(table) instanceof ResultSet) { 20275 ResultSet tableModel = (ResultSet) modelManager.getModel(table); 20276 if (tableModel != resultSetModel && !tableModel.getRelationRows().getHoldRelations().isEmpty()) { 20277 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 20278 impactRelation.setEffectType(effectType); 20279 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 20280 tableModel.getRelationRows())); 20281 impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 20282 resultSetModel.getRelationRows())); 20283 } 20284 } else if (modelManager.getModel(table) instanceof Table) { 20285 Table tableModel = (Table) modelManager.getModel(table); 20286 if (!tableModel.getRelationRows().getHoldRelations().isEmpty()) { 20287 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 20288 impactRelation.setEffectType(effectType); 20289 impactRelation.addSource( 20290 new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows())); 20291 impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 20292 resultSetModel.getRelationRows())); 20293 } 20294 } 20295 } 20296 } 20297 } 20298 20299 private void analyzeFunctionDataFlowRelation(Object gspObject, List<TParseTreeNode> functions, 20300 EffectType effectType) { 20301 for (int i = 0; i < functions.size(); i++) { 20302 TParseTreeNode functionCall = functions.get(i); 20303 if (functionCall instanceof TFunctionCall) { 20304 String functionName = DlineageUtil.getIdentifierNormalTableName( 20305 DlineageUtil.getFunctionNameWithArgNum((TFunctionCall) functionCall)); 20306 Procedure procedure = modelManager.getProcedureByName(functionName); 20307 if (procedure != null) { 20308 String procedureParent = getProcedureParentName(stmtStack.peek()); 20309 if (procedureParent != null) { 20310 Procedure caller = modelManager 20311 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 20312 if (caller != null) { 20313 CallRelationship callRelation = modelFactory.createCallRelation(); 20314 callRelation.setCallObject(functionCall); 20315 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 20316 callRelation.addSource(new ProcedureRelationshipElement(procedure)); 20317 if (isBuiltInFunctionName(((TFunctionCall)functionCall).getFunctionName())||isKeyword(((TFunctionCall)functionCall).getFunctionName())) { 20318 callRelation.setBuiltIn(true); 20319 } 20320 } 20321 } 20322 if (procedure.getProcedureObject() instanceof TCreateFunctionStmt) { 20323 TCreateFunctionStmt createFunction = (TCreateFunctionStmt)procedure.getProcedureObject(); 20324 TTypeName dataType = createFunction.getReturnDataType(); 20325 if (dataType!=null && dataType.getTypeOfList() != null && dataType.getTypeOfList().getColumnDefList() != null) { 20326 Object modelObject = modelManager.getModel(gspObject); 20327 if(modelObject instanceof ResultColumn) { 20328 ResultColumn resultColumn = (ResultColumn)modelObject; 20329 ResultSet resultSet = resultColumn.getResultSet(); 20330 for (int j = 0; j < dataType.getTypeOfList().getColumnDefList().size(); j++) { 20331 TObjectName columnName = new TObjectName(); 20332 if( dataType.getDataType() == EDataType.array_t) { 20333// columnName.setString(resultColumn.getName() + ".array." 20334// + dataType.getTypeOfList().getColumnDefList().getColumn(j) 20335// .getColumnName().getColumnNameOnly()); 20336 columnName.setString(resultColumn.getName() + "." 20337 + dataType.getTypeOfList().getColumnDefList().getColumn(j) 20338 .getColumnName().getColumnNameOnly()); 20339 } 20340 else { 20341 columnName.setString(resultColumn.getName() + "." 20342 + dataType.getTypeOfList().getColumnDefList().getColumn(j) 20343 .getColumnName().getColumnNameOnly()); 20344 } 20345 ResultColumn sturctColumn = modelFactory.createResultColumn(resultSet, columnName, 20346 true); 20347 sturctColumn.setStruct(true); 20348 Function sourceFunction = (Function)createFunction(functionCall); 20349 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 20350 relation.setEffectType(effectType); 20351 relation.setTarget(new ResultColumnRelationshipElement(sturctColumn)); 20352 if (sourceFunction.getColumns() != null && !sourceFunction.getColumns().isEmpty()) { 20353 for (ResultColumn column : sourceFunction.getColumns()) { 20354 relation.addSource(new ResultColumnRelationshipElement(column)); 20355 } 20356 } 20357 } 20358 resultSet.getColumns().remove(resultColumn); 20359 } 20360 return; 20361 } 20362 } 20363 } 20364 } 20365 20366 if(gspObject instanceof TResultColumn) { 20367 TResultColumn resultColumn = (TResultColumn)gspObject; 20368 if(resultColumn.getAliasClause()!=null && resultColumn.getAliasClause().getColumns()!=null) { 20369 for(TObjectName columnName: resultColumn.getAliasClause().getColumns()) { 20370 analyzeFunctionDataFlowRelation(columnName, Arrays.asList(functionCall), effectType, null); 20371 } 20372 return; 20373 } 20374 } 20375 analyzeFunctionDataFlowRelation(gspObject, Arrays.asList(functionCall), effectType, null); 20376 } 20377 } 20378 20379 private void analyzeFunctionDataFlowRelation(Object gspObject, List<TParseTreeNode> functions, 20380 EffectType effectType, Process process) { 20381 20382 Object modelObject = modelManager.getModel(gspObject); 20383 if (modelObject == null) { 20384 if (gspObject instanceof ResultColumn || gspObject instanceof TableColumn) { 20385 modelObject = gspObject; 20386 } 20387 } 20388 20389 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 20390 relation.setEffectType(effectType); 20391 relation.setProcess(process); 20392 20393 if (modelObject instanceof ResultColumn) { 20394 relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) modelObject)); 20395 20396 } else if (modelObject instanceof TableColumn) { 20397 relation.setTarget(new TableColumnRelationshipElement((TableColumn) modelObject)); 20398 20399 } else { 20400 throw new UnsupportedOperationException(); 20401 } 20402 20403 for (int i = 0; i < functions.size(); i++) { 20404 TParseTreeNode functionCall = functions.get(i); 20405 20406 if (functionCall instanceof TFunctionCall) { 20407 TFunctionCall call = (TFunctionCall) functionCall; 20408 Procedure callee = modelManager.getProcedureByName( 20409 DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(call))); 20410 if (callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(call))) { 20411 analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(call))); 20412 callee = modelManager.getProcedureByName( 20413 DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(call))); 20414 } 20415 20416 if (callee != null) { 20417 String procedureParent = getProcedureParentName(stmtStack.peek()); 20418 if (procedureParent != null) { 20419 Procedure caller = modelManager 20420 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 20421 if (caller != null) { 20422 CallRelationship callRelation = modelFactory.createCallRelation(); 20423 callRelation.setCallObject(functionCall); 20424 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 20425 callRelation.addSource(new ProcedureRelationshipElement(callee)); 20426 if (isBuiltInFunctionName(call.getFunctionName()) || isKeyword(call.getFunctionName())) { 20427 callRelation.setBuiltIn(true); 20428 } 20429 } 20430 } 20431 if (callee.getArguments() != null) { 20432 for (int j = 0; j < callee.getArguments().size(); j++) { 20433 Argument argument = callee.getArguments().get(j); 20434 Variable variable = modelFactory.createVariable(callee, argument.getName(), false); 20435 if(variable!=null) { 20436 if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) { 20437 Transform transform = new Transform(); 20438 transform.setType(Transform.FUNCTION); 20439 transform.setCode(call); 20440 variable.getColumns().get(0).setTransform(transform); 20441 } 20442 Process callProcess = modelFactory.createProcess(call); 20443 variable.addProcess(callProcess); 20444 analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), call, j, callProcess); 20445 } 20446 } 20447 } 20448 Set<Object> functionTableModelObjs = modelManager.getFunctionTable(DlineageUtil 20449 .getIdentifierNormalTableName(call.getFunctionName().toString())); 20450 if (functionTableModelObjs != null) { 20451 modelManager.bindModel(call, functionTableModelObjs.iterator().next()); 20452 for (Object functionTableModelObj : functionTableModelObjs) { 20453 if (functionTableModelObj instanceof ResultSet) { 20454 ResultSet resultSet = (ResultSet) functionTableModelObj; 20455 for (ResultColumn column : resultSet.getColumns()) { 20456 relation.addSource(new ResultColumnRelationshipElement(column)); 20457 } 20458 } 20459 } 20460 } 20461 continue; 20462 } 20463 } 20464 20465 20466 Object functionModel = createFunction(functionCall); 20467 if (functionModel instanceof Function) { 20468 Function sourceFunction = (Function)functionModel; 20469 if (sourceFunction.getColumns() != null && !sourceFunction.getColumns().isEmpty()) { 20470 for (ResultColumn column : sourceFunction.getColumns()) { 20471 relation.addSource(new ResultColumnRelationshipElement(column)); 20472 } 20473 } 20474 else if (functionCall instanceof TFunctionCall) { 20475 relation.addSource(new ResultColumnRelationshipElement((FunctionResultColumn) modelManager 20476 .getModel(((TFunctionCall) functionCall).getFunctionName()))); 20477 } else if (functionCall instanceof TCaseExpression) { 20478 relation.addSource(new ResultColumnRelationshipElement((FunctionResultColumn) modelManager 20479 .getModel(((TCaseExpression) functionCall).getWhenClauseItemList()))); 20480 } 20481 20482 if (sourceFunction != null && !sourceFunction.getRelationRows().getHoldRelations().isEmpty()) { 20483 boolean find = false; 20484 if (modelObject instanceof ResultColumn) { 20485 ResultSetRelationRows targetRelationRows = ((ResultColumn) modelObject).getResultSet().getRelationRows(); 20486 if(targetRelationRows.hasRelation()) { 20487 for(Relationship relationship: targetRelationRows.getHoldRelations()) { 20488 if(relationship.getSources().contains(sourceFunction.getRelationRows())) { 20489 find = true; 20490 break; 20491 } 20492 } 20493 } 20494 } 20495 else if (modelObject instanceof TableColumn) { 20496 TableRelationRows targetRelationRows = ((TableColumn) modelObject).getTable().getRelationRows(); 20497 if(targetRelationRows.hasRelation()) { 20498 for(Relationship relationship: targetRelationRows.getHoldRelations()) { 20499 if(relationship.getSources().contains(sourceFunction.getRelationRows())) { 20500 find = true; 20501 break; 20502 } 20503 } 20504 } 20505 } 20506 20507 if (!find) { 20508 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 20509 impactRelation.setEffectType(EffectType.select); 20510 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 20511 sourceFunction.getRelationRows())); 20512 if (modelObject instanceof ResultColumn) { 20513 impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 20514 ((ResultColumn) modelObject).getResultSet().getRelationRows())); 20515 } else if (modelObject instanceof TableColumn) { 20516 impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>( 20517 ((TableColumn) modelObject).getTable().getRelationRows())); 20518 } 20519 } 20520 } 20521 } else if (functionModel instanceof Table) { 20522 TFunctionCall call = (TFunctionCall) functionCall; 20523 String functionName = call.getFunctionName().toString(); 20524 boolean flag = false; 20525 if (functionName.indexOf(".") != -1) { 20526 String columnName = functionName.substring(functionName.indexOf(".") + 1); 20527 for (TableColumn tableColumn : ((Table) functionModel).getColumns()) { 20528 if (getColumnName(tableColumn.getName()).equalsIgnoreCase(columnName)) { 20529 TableColumnRelationshipElement element = new TableColumnRelationshipElement(tableColumn); 20530 relation.addSource(element); 20531 flag = true; 20532 break; 20533 } 20534 } 20535 } 20536 20537 if (!flag) { 20538 TableColumn tableColumn = modelFactory.createTableColumn((Table) functionModel, 20539 ((TFunctionCall) functionCall)); 20540 TableColumnRelationshipElement element = new TableColumnRelationshipElement(tableColumn); 20541 relation.addSource(element); 20542 } 20543 } 20544 } 20545 20546 } 20547 20548 private void analyzeSubqueryDataFlowRelation(Object gspObject, List<TSelectSqlStatement> subquerys, 20549 EffectType effectType) { 20550 analyzeSubqueryDataFlowRelation(gspObject, subquerys, effectType, null); 20551 } 20552 20553 private void analyzeSubqueryDataFlowRelation(Object gspObject, List<TSelectSqlStatement> subquerys, 20554 EffectType effectType, Process process) { 20555 20556 Object modelObject = modelManager.getModel(gspObject); 20557 if (modelObject == null) { 20558 if (gspObject instanceof ResultColumn || gspObject instanceof TableColumn) { 20559 modelObject = gspObject; 20560 } 20561 } 20562 20563 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 20564 relation.setEffectType(effectType); 20565 relation.setProcess(process); 20566 20567 if (modelObject instanceof ResultColumn) { 20568 relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) modelObject)); 20569 20570 } else if (modelObject instanceof TableColumn) { 20571 relation.setTarget(new TableColumnRelationshipElement((TableColumn) modelObject)); 20572 20573 } else { 20574 throw new UnsupportedOperationException(); 20575 } 20576 20577 for (int i = 0; i < subquerys.size(); i++) { 20578 TSelectSqlStatement subquery = subquerys.get(i); 20579 ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery); 20580 if (resultSetModel != null && resultSetModel.getColumns() != null) { 20581 for (ResultColumn column : resultSetModel.getColumns()) { 20582 relation.addSource(new ResultColumnRelationshipElement(column)); 20583 } 20584 } 20585 20586 if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 20587 boolean find = false; 20588 if (modelObject instanceof ResultColumn) { 20589 ResultSetRelationRows targetRelationRows = ((ResultColumn) modelObject).getResultSet().getRelationRows(); 20590 if(targetRelationRows.hasRelation()) { 20591 for(Relationship relationship: targetRelationRows.getHoldRelations()) { 20592 if(relationship.getSources().contains(resultSetModel.getRelationRows())) { 20593 find = true; 20594 break; 20595 } 20596 } 20597 } 20598 } 20599 else if (modelObject instanceof TableColumn) { 20600 TableRelationRows targetRelationRows = ((TableColumn) modelObject).getTable().getRelationRows(); 20601 if(targetRelationRows.hasRelation()) { 20602 for(Relationship relationship: targetRelationRows.getHoldRelations()) { 20603 if(relationship.getSources().contains(resultSetModel.getRelationRows())) { 20604 find = true; 20605 break; 20606 } 20607 } 20608 } 20609 } 20610 20611 if (!find) { 20612 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 20613 impactRelation.setEffectType(EffectType.select); 20614 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 20615 resultSetModel.getRelationRows())); 20616 if (modelObject instanceof ResultColumn) { 20617 impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 20618 ((ResultColumn) modelObject).getResultSet().getRelationRows())); 20619 } else if (modelObject instanceof TableColumn) { 20620 impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>( 20621 ((TableColumn) modelObject).getTable().getRelationRows())); 20622 } 20623 } 20624 } 20625 } 20626 20627 } 20628 20629 private Object createFunction(TParseTreeNode functionCall) { 20630 if (functionCall instanceof TFunctionCall) { 20631 TFunctionCall functionObj = (TFunctionCall) functionCall; 20632 20633 // Generic structured-dataflow dispatch. When a vendor adapter (e.g. 20634 // Spark from_json+explode) returns a descriptor, model the function 20635 // as a structured generator: per-field result columns linked to 20636 // exact structured source paths such as nodes[*].key. When no 20637 // adapter matches, fall through to the existing function logic 20638 // unchanged. 20639 StructuredAdapterContext sctx = new StructuredAdapterContext(option.getVendor()); 20640 StructuredDataflowDescriptor sdescriptor = 20641 StructuredDataflowRegistry.defaultRegistry().describe(functionObj, sctx); 20642 if (sdescriptor != null) { 20643 Function structuredFn = createStructuredDataflowFunction(sdescriptor); 20644 if (structuredFn != null) { 20645 return structuredFn; 20646 } 20647 } 20648 20649 if (!isBuiltInFunctionName(functionObj.getFunctionName())) { 20650 TCustomSqlStatement stmt = stmtStack.peek(); 20651 String procedureParent = getProcedureParentName(stmt); 20652 if (procedureParent != null) { 20653 Procedure procedureCallee = modelManager.getProcedureByName(DlineageUtil 20654 .getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionObj))); 20655 if (procedureCallee != null) { 20656 if (procedureParent != null) { 20657 Procedure caller = modelManager 20658 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 20659 if (caller != null) { 20660 CallRelationship callRelation = modelFactory.createCallRelation(); 20661 callRelation.setCallObject(functionCall); 20662 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 20663 callRelation.addSource(new ProcedureRelationshipElement(procedureCallee)); 20664 if(isBuiltInFunctionName(functionObj.getFunctionName()) || isKeyword(functionObj.getFunctionName())){ 20665 callRelation.setBuiltIn(true); 20666 } 20667 } 20668 } 20669 if (procedureCallee.getArguments() != null) { 20670 for (int j = 0; j < procedureCallee.getArguments().size(); j++) { 20671 Argument argument = procedureCallee.getArguments().get(j); 20672 Variable variable = modelFactory.createVariable(procedureCallee, argument.getName(), false); 20673 if(variable!=null) { 20674 if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) { 20675 Transform transform = new Transform(); 20676 transform.setType(Transform.FUNCTION); 20677 transform.setCode(functionObj); 20678 variable.getColumns().get(0).setTransform(transform); 20679 } 20680 Process process = modelFactory.createProcess(functionObj); 20681 variable.addProcess(process); 20682 analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionObj, j, process); 20683 } 20684 } 20685 } 20686 } else { 20687 TFunctionCall call = (TFunctionCall)functionCall; 20688 String functionName = call.getFunctionName().toString(); 20689 if (functionName.indexOf(".") != -1) { 20690 Table functionTable = modelManager 20691 .getTableByName(functionName.substring(0, functionName.indexOf("."))); 20692 if (functionTable != null) { 20693 String columnName = functionName.substring(functionName.indexOf(".") + 1); 20694 for (TableColumn tableColumn : functionTable.getColumns()) { 20695 if (getColumnName(tableColumn.getName()).equalsIgnoreCase(columnName)) { 20696 return functionTable; 20697 } 20698 } 20699 } 20700 } 20701 Function function = modelFactory.createFunction(call); 20702 if (procedureParent != null) { 20703 Procedure caller = modelManager 20704 .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent)); 20705 if (caller != null) { 20706 CallRelationship callRelation = modelFactory.createCallRelation(); 20707 callRelation.setCallObject(functionCall); 20708 callRelation.setTarget(new ProcedureRelationshipElement(caller)); 20709 callRelation.addSource(new FunctionRelationshipElement(function)); 20710 if(isBuiltInFunctionName(functionObj.getFunctionName()) || isKeyword(functionObj.getFunctionName())){ 20711 callRelation.setBuiltIn(true); 20712 } 20713 } 20714 } 20715 } 20716 } 20717 } else if (isConstantFunction(functionObj.getFunctionName()) 20718 && (functionObj.getArgs() == null || functionObj.getArgs().size() == 0)) { 20719 if (option.isShowConstantTable()) { 20720 Table constantTable = modelFactory.createConstantsTable(stmtStack.peek()); 20721 modelFactory.createTableColumn(constantTable, functionObj); 20722 return constantTable; 20723 } else { 20724 return null; 20725 } 20726 } 20727 20728 if (functionObj.getFunctionType() == EFunctionType.struct_t) { 20729 Function function = modelFactory.createFunction((TFunctionCall) functionCall); 20730 if(functionObj instanceof TTableFunction) { 20731 TTableFunction tableFunction = (TTableFunction) functionObj; 20732 if (tableFunction.getFieldValues() != null) { 20733 for (int i = 0; i < tableFunction.getFieldValues().size(); i++) { 20734 TResultColumn resultColumn = tableFunction.getFieldValues().getResultColumn(i); 20735 if (resultColumn.getAliasClause() != null) { 20736 ResultColumn column = modelFactory.createFunctionResultColumn(function, 20737 resultColumn.getAliasClause().getAliasName()); 20738 columnsInExpr visitor = new columnsInExpr(); 20739 resultColumn.getExpr().inOrderTraverse(visitor); 20740 List<TObjectName> objectNames = visitor.getObjectNames(); 20741 List<TParseTreeNode> functions = visitor.getFunctions(); 20742 if (functions != null && !functions.isEmpty()) { 20743 analyzeFunctionDataFlowRelation(column, functions, EffectType.function); 20744 } 20745 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 20746 if (subquerys != null && !subquerys.isEmpty()) { 20747 analyzeSubqueryDataFlowRelation(column, subquerys, EffectType.function); 20748 } 20749 analyzeDataFlowRelation(column, objectNames, EffectType.function, functions); 20750 List<TParseTreeNode> constants = visitor.getConstants(); 20751 analyzeConstantDataFlowRelation(column, constants, EffectType.function, functions); 20752 } else if (resultColumn.getFieldAttr() != null) { 20753 ResultColumn column = modelFactory.createFunctionResultColumn(function, 20754 resultColumn.getFieldAttr()); 20755 analyzeDataFlowRelation(column, Arrays.asList(resultColumn.getFieldAttr()), EffectType.function, null); 20756 } else if (resultColumn.getExpr() != null) { 20757 if (resultColumn.getExpr().getFunctionCall() != null) { 20758 Function resultColumnFunction = (Function) createFunction( 20759 resultColumn.getExpr().getFunctionCall()); 20760 String functionName = getResultSetName(function); 20761 for (int j = 0; j < resultColumnFunction.getColumns().size(); j++) { 20762 TObjectName columnName = new TObjectName(); 20763 if (resultColumn.getAliasClause() != null) { 20764 columnName.setString(resultColumn.getAliasClause() + "." + getColumnNameOnly( 20765 resultColumnFunction.getColumns().get(j).getName())); 20766 } else { 20767 columnName.setString(functionName + "." + getColumnNameOnly( 20768 resultColumnFunction.getColumns().get(j).getName())); 20769 } 20770 ResultColumn functionResultColumn = modelFactory.createResultColumn(function, 20771 columnName); 20772 DataFlowRelationship relationship = modelFactory.createDataFlowRelation(); 20773 relationship.setTarget(new ResultColumnRelationshipElement(functionResultColumn)); 20774 relationship.addSource(new ResultColumnRelationshipElement( 20775 resultColumnFunction.getColumns().get(j))); 20776 } 20777 } 20778 else if (resultColumn.getExpr().getCaseExpression() != null) { 20779 function = modelFactory.createFunction(resultColumn.getExpr().getCaseExpression()); 20780 ResultColumn column = modelFactory.createFunctionResultColumn(function, 20781 ((TCaseExpression) resultColumn.getExpr().getCaseExpression()).getWhenClauseItemList()); 20782 analyzeFunctionArgumentsDataFlowRelation(column, functionCall); 20783 } 20784 } 20785 } 20786 return function; 20787 } 20788 } 20789 else if(functionObj instanceof TFunctionCall) { 20790 20791 } 20792 } 20793 20794 // BigQuery array_agg(table_alias) row-reference expansion 20795 if (functionObj.getFunctionType() == EFunctionType.array_agg_t 20796 && option.getVendor() == EDbVendor.dbvbigquery 20797 && functionObj.getArgs() != null 20798 && functionObj.getArgs().size() == 1) { 20799 20800 TExpression arg0 = functionObj.getArgs().getExpression(0); 20801 if (arg0 != null 20802 && arg0.getExpressionType() == EExpressionType.simple_object_name_t) { 20803 20804 TObjectName on = arg0.getObjectOperand(); 20805 if (isArrayAggRowReference(on)) { 20806 Function function = (Function) modelManager.getModel(functionCall); 20807 if (function == null) { 20808 function = modelFactory.createFunction((TFunctionCall) functionCall); 20809 } 20810 20811 // Only bind once (avoid duplicate processing when 20812 // createFunction is called from analyzeFunctionDataFlowRelation) 20813 if (function.getColumns() == null || function.getColumns().isEmpty()) { 20814 TTable srcTable = on.getSourceTable(); 20815 String tableAlias = srcTable.getAliasName() != null 20816 ? srcTable.getAliasName().toString() : null; 20817 20818 Table sourceTable = (Table) modelManager.getModel(srcTable); 20819 sourceTable.removeColumn(tableAlias); 20820 20821 // Collect inferred column names from ORDER BY (in function) 20822 // and GROUP BY (in enclosing SELECT). Excludes the table alias. 20823 List<TObjectName> inferredColumns = collectRowReferenceInferredColumns( 20824 functionObj, tableAlias); 20825 20826 // Create a single * function result column carrying star-link 20827 // metadata for the inferred columns and direct source edges 20828 // for * and each inferred column. 20829 createRowReferenceStarColumn(function, srcTable, inferredColumns); 20830 } 20831 20832 return function; 20833 } 20834 } 20835 } 20836 20837 if (functionObj.getFunctionType() == EFunctionType.array_t || functionObj.getFunctionType() == EFunctionType.array_agg_t) { 20838 Function function = modelFactory.createFunction((TFunctionCall) functionCall); 20839 if(functionObj.getArgs()!=null) { 20840 if(functionObj.getArgs().getExpression(0).getSubQuery()!=null) { 20841 TSelectSqlStatement stmt = functionObj.getArgs().getExpression(0).getSubQuery(); 20842 analyzeSelectStmt(stmt); 20843 ResultSet resultset = (ResultSet) modelManager.getModel(stmt); 20844 for (int i = 0; i < resultset.getColumns().size(); i++) { 20845 ResultColumn sourceColumn = resultset.getColumns().get(i); 20846 TObjectName columnName = new TObjectName(); 20847 columnName.setString(sourceColumn.getName()); 20848 ResultColumn resultColumn = modelFactory.createFunctionResultColumn(function, 20849 columnName); 20850 DataFlowRelationship relationship = modelFactory.createDataFlowRelation(); 20851 relationship.setTarget(new ResultColumnRelationshipElement(resultColumn)); 20852 relationship.addSource( 20853 new ResultColumnRelationshipElement(sourceColumn)); 20854 } 20855 return function; 20856 } 20857 else if (functionObj.getArgs().getExpression(0).getExpressionType() == EExpressionType.function_t) { 20858 Object functionTableModelObj = createFunction(functionObj.getArgs().getExpression(0).getFunctionCall()); 20859 if (functionTableModelObj instanceof ResultSet) { 20860 ResultSet resultset = (ResultSet) functionTableModelObj; 20861 for (int i = 0; i < resultset.getColumns().size(); i++) { 20862 ResultColumn sourceColumn = resultset.getColumns().get(i); 20863 TObjectName columnName = new TObjectName(); 20864 columnName.setString(sourceColumn.getName()); 20865 ResultColumn resultColumn = modelFactory.createFunctionResultColumn(function, columnName); 20866 DataFlowRelationship relationship = modelFactory.createDataFlowRelation(); 20867 relationship.setTarget(new ResultColumnRelationshipElement(resultColumn)); 20868 relationship.addSource(new ResultColumnRelationshipElement(sourceColumn)); 20869 } 20870 return function; 20871 } 20872 } 20873 } 20874 } 20875 20876 Function function = modelFactory.createFunction((TFunctionCall) functionCall); 20877 ResultColumn column = modelFactory.createFunctionResultColumn(function, 20878 ((TFunctionCall) functionCall).getFunctionName()); 20879 if ("COUNT".equalsIgnoreCase(((TFunctionCall) functionCall).getFunctionName().toString())) { 20880 // @see https://e.gitee.com/gudusoft/issues/list?issue=I40NUP 20881 // COUNT特殊处理,不和参数关联 20882 if (option.isShowCountTableColumn()) { 20883 analyzeFunctionArgumentsDataFlowRelation(column, functionCall); 20884 } 20885 } else { 20886 boolean isCustomFunction = analyzeCustomFunctionCall((TFunctionCall)functionCall); 20887// if(!isCustomFunction) 20888 { 20889 analyzeFunctionArgumentsDataFlowRelation(column, functionCall); 20890 } 20891 Set<Object> functionTableModelObjs = modelManager.getFunctionTable(getIdentifiedFunctionName(function)); 20892 if(functionTableModelObjs!=null) { 20893 for(Object functionTableModelObj: functionTableModelObjs) { 20894 if (functionTableModelObj instanceof ResultSet) { 20895 ResultSet functionTableModel = (ResultSet) functionTableModelObj; 20896 if (functionTableModel.getColumns() != null) { 20897 for (int j = 0; j < functionTableModel.getColumns().size(); j++) { 20898 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 20899 relation.setEffectType(EffectType.select); 20900 relation.setTarget(new ResultColumnRelationshipElement(column)); 20901 relation.addSource(new ResultColumnRelationshipElement( 20902 functionTableModel.getColumns().get(j))); 20903 } 20904 } 20905 } 20906 } 20907 } 20908 } 20909 return function; 20910 } else if (functionCall instanceof TCaseExpression) { 20911 Function function = modelFactory.createFunction((TCaseExpression) functionCall); 20912 ResultColumn column = modelFactory.createFunctionResultColumn(function, 20913 ((TCaseExpression) functionCall).getWhenClauseItemList()); 20914 analyzeFunctionArgumentsDataFlowRelation(column, functionCall); 20915 return function; 20916 } else if (functionCall instanceof TObjectName) { 20917 Function function = modelFactory.createFunction((TObjectName) functionCall); 20918 TObjectName columnName = new TObjectName(); 20919 columnName.setString(function.getFunctionName()); 20920 ResultColumn column = modelFactory.createResultColumn(function, 20921 columnName); 20922 analyzeFunctionArgumentsDataFlowRelation(column, functionCall); 20923 return function; 20924 } 20925 return null; 20926 } 20927 20928 protected String getIdentifiedFunctionName(Function function) { 20929 return DlineageUtil.getIdentifierNormalFunctionName(function.getFunctionName()); 20930 } 20931 20932 private boolean isConstantFunction(TObjectName functionName) { 20933 boolean result = CONSTANT_BUILTIN_FUNCTIONS.contains(functionName.toString().toUpperCase()); 20934 if (result) { 20935 return true; 20936 } 20937 return false; 20938 } 20939 20940 private void analyzeFunctionArgumentsDataFlowRelation(Object resultColumn, TParseTreeNode gspObject) { 20941 List<TExpression> directExpressions = new ArrayList<TExpression>(); 20942 List<TExpression> indirectExpressions = new ArrayList<TExpression>(); 20943 List<TExpression> conditionExpressions = new ArrayList<TExpression>(); 20944 if (gspObject instanceof TFunctionCall) { 20945 TFunctionCall functionCall = (TFunctionCall) gspObject; 20946 getFunctionExpressions(directExpressions, indirectExpressions, functionCall); 20947 } else if (gspObject instanceof TCaseExpression) { 20948 TCaseExpression expr = (TCaseExpression) gspObject; 20949 TExpression inputExpr = expr.getInput_expr(); 20950 if (inputExpr != null) { 20951 if(option.isShowCaseWhenAsDirect()){ 20952 directExpressions.add(inputExpr); 20953 } 20954 else { 20955 conditionExpressions.add(inputExpr); 20956 } 20957 } 20958 TExpression defaultExpr = expr.getElse_expr(); 20959 if (defaultExpr != null) { 20960 directExpressions.add(defaultExpr); 20961 } 20962 TWhenClauseItemList list = expr.getWhenClauseItemList(); 20963 for (int i = 0; i < list.size(); i++) { 20964 TWhenClauseItem element = list.getWhenClauseItem(i); 20965 if(option.isShowCaseWhenAsDirect()){ 20966 directExpressions.add(element.getComparison_expr()); 20967 } 20968 else { 20969 conditionExpressions.add(element.getComparison_expr()); 20970 } 20971 directExpressions.add(element.getReturn_expr()); 20972 } 20973 } 20974 20975 for (int j = 0; j < directExpressions.size(); j++) { 20976 columnsInExpr visitor = new columnsInExpr(); 20977 directExpressions.get(j).inOrderTraverse(visitor); 20978 20979 List<TObjectName> objectNames = visitor.getObjectNames(); 20980 List<TParseTreeNode> functions = visitor.getFunctions(); 20981 20982 if (functions != null && !functions.isEmpty()) { 20983 analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function); 20984 } 20985 20986 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 20987 if (subquerys != null && !subquerys.isEmpty()) { 20988 analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.function); 20989 } 20990 20991 analyzeDataFlowRelation(resultColumn, objectNames, EffectType.function, functions); 20992 20993 List<TParseTreeNode> constants = visitor.getConstants(); 20994 analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.function, functions); 20995 } 20996 20997 conditionExpressions.addAll(indirectExpressions); 20998 for (int j = 0; j < conditionExpressions.size(); j++) { 20999 analyzeFilterCondition(resultColumn, conditionExpressions.get(j), null, null, EffectType.function); 21000 } 21001 } 21002 21003 private void analyzeFunctionArgumentsDataFlowRelation(Object resultColumn, TCallStatement callStatment, int argumentIndex, Process process) { 21004 List<TExpression> directExpressions = new ArrayList<TExpression>(); 21005 List<TExpression> indirectExpressions = new ArrayList<TExpression>(); 21006 List<TExpression> conditionExpressions = new ArrayList<TExpression>(); 21007 21008 getFunctionExpressions(directExpressions, indirectExpressions, callStatment, argumentIndex); 21009 21010 for (int j = 0; j < directExpressions.size(); j++) { 21011 columnsInExpr visitor = new columnsInExpr(); 21012 directExpressions.get(j).inOrderTraverse(visitor); 21013 21014 List<TObjectName> objectNames = visitor.getObjectNames(); 21015 List<TParseTreeNode> functions = visitor.getFunctions(); 21016 21017 if (functions != null && !functions.isEmpty()) { 21018 analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function); 21019 } 21020 21021 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 21022 if (subquerys != null && !subquerys.isEmpty()) { 21023 analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.function); 21024 } 21025 21026 DataFlowRelationship relation = analyzeDataFlowRelation(resultColumn, objectNames, EffectType.function, functions); 21027 if (relation != null) { 21028 relation.setProcess(process); 21029 } 21030 21031 List<TParseTreeNode> constants = visitor.getConstants(); 21032 analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.function, functions); 21033 } 21034 21035 conditionExpressions.addAll(indirectExpressions); 21036 for (int j = 0; j < conditionExpressions.size(); j++) { 21037 analyzeFilterCondition(resultColumn, conditionExpressions.get(j), null, null, EffectType.function); 21038 } 21039 } 21040 21041 private void analyzeFunctionArgumentsDataFlowRelation(Object resultColumn, TDb2CallStmt callStatment, int argumentIndex, Process process) { 21042 List<TExpression> directExpressions = new ArrayList<TExpression>(); 21043 List<TExpression> indirectExpressions = new ArrayList<TExpression>(); 21044 List<TExpression> conditionExpressions = new ArrayList<TExpression>(); 21045 21046 getFunctionExpressions(directExpressions, indirectExpressions, callStatment, argumentIndex); 21047 21048 for (int j = 0; j < directExpressions.size(); j++) { 21049 columnsInExpr visitor = new columnsInExpr(); 21050 directExpressions.get(j).inOrderTraverse(visitor); 21051 21052 List<TObjectName> objectNames = visitor.getObjectNames(); 21053 List<TParseTreeNode> functions = visitor.getFunctions(); 21054 21055 if (functions != null && !functions.isEmpty()) { 21056 analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function); 21057 } 21058 21059 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 21060 if (subquerys != null && !subquerys.isEmpty()) { 21061 analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.function); 21062 } 21063 21064 DataFlowRelationship relation = analyzeDataFlowRelation(resultColumn, objectNames, EffectType.function, functions); 21065 if (relation != null) { 21066 relation.setProcess(process); 21067 } 21068 21069 List<TParseTreeNode> constants = visitor.getConstants(); 21070 analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.function, functions); 21071 } 21072 21073 conditionExpressions.addAll(indirectExpressions); 21074 for (int j = 0; j < conditionExpressions.size(); j++) { 21075 analyzeFilterCondition(resultColumn, conditionExpressions.get(j), null, null, EffectType.function); 21076 } 21077 } 21078 21079 private void analyzeFunctionArgumentsDataFlowRelation(Object resultColumn, TFunctionCall functionCall, int argumentIndex, Process process) { 21080 List<TExpression> directExpressions = new ArrayList<TExpression>(); 21081 List<TExpression> indirectExpressions = new ArrayList<TExpression>(); 21082 List<TExpression> conditionExpressions = new ArrayList<TExpression>(); 21083 21084 getFunctionExpressions(directExpressions, indirectExpressions, functionCall, argumentIndex); 21085 21086 for (int j = 0; j < directExpressions.size(); j++) { 21087 columnsInExpr visitor = new columnsInExpr(); 21088 directExpressions.get(j).inOrderTraverse(visitor); 21089 21090 List<TObjectName> objectNames = visitor.getObjectNames(); 21091 List<TParseTreeNode> functions = visitor.getFunctions(); 21092 21093 if (functions != null && !functions.isEmpty()) { 21094 analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function); 21095 } 21096 21097 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 21098 if (subquerys != null && !subquerys.isEmpty()) { 21099 analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.function); 21100 } 21101 21102 DataFlowRelationship relation = analyzeDataFlowRelation(resultColumn, objectNames, EffectType.function, functions); 21103 if (relation != null) { 21104 relation.setProcess(process); 21105 } 21106 21107 List<TParseTreeNode> constants = visitor.getConstants(); 21108 analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.function, functions); 21109 } 21110 21111 conditionExpressions.addAll(indirectExpressions); 21112 for (int j = 0; j < conditionExpressions.size(); j++) { 21113 analyzeFilterCondition(resultColumn, conditionExpressions.get(j), null, null, EffectType.function); 21114 } 21115 } 21116 21117 private void analyzeFunctionArgumentsDataFlowRelation(Object resultColumn, TMssqlExecute functionCall, String argumentName, int argumentIndex, Process process) { 21118 List<TExpression> directExpressions = new ArrayList<TExpression>(); 21119 List<TExpression> indirectExpressions = new ArrayList<TExpression>(); 21120 List<TExpression> conditionExpressions = new ArrayList<TExpression>(); 21121 21122 getFunctionExpressions(directExpressions, indirectExpressions, functionCall, argumentName, argumentIndex); 21123 21124 for (int j = 0; j < directExpressions.size(); j++) { 21125 columnsInExpr visitor = new columnsInExpr(); 21126 directExpressions.get(j).inOrderTraverse(visitor); 21127 21128 List<TObjectName> objectNames = visitor.getObjectNames(); 21129 List<TParseTreeNode> functions = visitor.getFunctions(); 21130 21131 if (functions != null && !functions.isEmpty()) { 21132 analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function); 21133 } 21134 21135 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 21136 if (subquerys != null && !subquerys.isEmpty()) { 21137 analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.function); 21138 } 21139 21140 DataFlowRelationship relation = analyzeDataFlowRelation(resultColumn, objectNames, EffectType.function, functions); 21141 if (relation != null) { 21142 relation.setProcess(process); 21143 } 21144 21145 List<TParseTreeNode> constants = visitor.getConstants(); 21146 analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.function, functions); 21147 } 21148 21149 conditionExpressions.addAll(indirectExpressions); 21150 for (int j = 0; j < conditionExpressions.size(); j++) { 21151 analyzeFilterCondition(resultColumn, conditionExpressions.get(j), null, null, EffectType.function); 21152 } 21153 } 21154 21155 21156 private static void addResultColumnListExpressions( 21157 TResultColumnList list, List<TExpression> target) { 21158 if (list == null) return; 21159 for (int k = 0; k < list.size(); k++) { 21160 TExpression e = list.getResultColumn(k).getExpr(); 21161 if (e != null) target.add(e); 21162 } 21163 } 21164 21165 private static void addPassingClauseExpressions( 21166 TFunctionCall fc, List<TExpression> target) { 21167 TResultColumnList list = null; 21168 if (fc.getXmlPassingClause() != null 21169 && fc.getXmlPassingClause().getPassingList() != null) { 21170 list = fc.getXmlPassingClause().getPassingList(); 21171 } else if (fc.getPassingClause() != null 21172 && fc.getPassingClause().getPassingList() != null) { 21173 list = fc.getPassingClause().getPassingList(); 21174 } 21175 addResultColumnListExpressions(list, target); 21176 } 21177 21178 private void collectOracleXmlFunctionExpressions( 21179 TFunctionCall fc, 21180 List<TExpression> direct, 21181 List<TExpression> indirect) { 21182 21183 if (option.getVendor() != EDbVendor.dbvoracle) return; 21184 21185 // XMLELEMENT: value exprs + XMLATTRIBUTES exprs (direct) 21186 addResultColumnListExpressions(fc.getXMLElementValueExprList(), direct); 21187 if (fc.getXMLAttributesClause() != null) { 21188 addResultColumnListExpressions( 21189 fc.getXMLAttributesClause().getValueExprList(), direct); 21190 } 21191 21192 // XMLFOREST (direct) 21193 addResultColumnListExpressions(fc.getXMLForestValueList(), direct); 21194 21195 // EXTRACT(XML) — AST-shape disambiguation (V3) 21196 // XML form populates getXMLType_Instance(); scalar EXTRACT(YEAR FROM d) does not. 21197 if (fc.getXMLType_Instance() != null) { 21198 direct.add(fc.getXMLType_Instance()); 21199 } 21200 21201 String name = fc.getFunctionName() == null 21202 ? "" : fc.getFunctionName().toString().toUpperCase(); 21203 21204 // XMLEXISTS indirect (filter) from PASSING expressions 21205 if ("XMLEXISTS".equals(name)) { 21206 addPassingClauseExpressions(fc, indirect); 21207 } 21208 21209 // XMLAGG / SYS_XMLAGG ORDER BY → indirect 21210 if (("XMLAGG".equals(name) || "SYS_XMLAGG".equals(name)) 21211 && fc.getSortClause() != null) { 21212 TOrderByItemList orderByList = fc.getSortClause().getItems(); 21213 if (orderByList != null) { 21214 for (int k = 0; k < orderByList.size(); k++) { 21215 TExpression e = orderByList.getOrderByItem(k).getSortKey(); 21216 if (e != null) indirect.add(e); 21217 } 21218 } 21219 } 21220 21221 // DELIBERATELY NOT HARVESTED (metadata, not data): 21222 // fc.getTypeExpression() — target type for XMLCAST 21223 // fc.getXMLElementNameExpr() — element tag identifier 21224 // XPath / XQuery literal strings that appear as function args 21225 // datatype / format / style tokens 21226 } 21227 21228 private void collectArrayAggOrderByExpressions( 21229 TFunctionCall fc, 21230 List<TExpression> direct, 21231 List<TExpression> indirect) { 21232 if (fc.getFunctionType() != EFunctionType.array_agg_t) return; 21233 21234 TOrderByItemList items = null; 21235 if (fc.getSortClause() != null) items = fc.getSortClause().getItems(); 21236 if (items == null || items.size() == 0) { 21237 items = fc.getOrderByList(); 21238 } 21239 if (items == null) return; 21240 21241 // Resolve source tables for ORDER BY columns that the parser 21242 // doesn't link (they're inside a function call, outside the 21243 // resolver's normal scope) 21244 TTable fallbackTable = null; 21245 if (!stmtStack.isEmpty() && stmtStack.peek() instanceof TSelectSqlStatement) { 21246 TTableList tables = ((TSelectSqlStatement) stmtStack.peek()).tables; 21247 if (tables != null && tables.size() > 0) { 21248 fallbackTable = tables.getTable(0); 21249 } 21250 } 21251 21252 for (int k = 0; k < items.size(); k++) { 21253 TExpression e = items.getOrderByItem(k).getSortKey(); 21254 if (e != null) { 21255 if (fallbackTable != null 21256 && e.getExpressionType() == EExpressionType.simple_object_name_t 21257 && e.getObjectOperand() != null 21258 && e.getObjectOperand().getSourceTable() == null) { 21259 e.getObjectOperand().setSourceTable(fallbackTable); 21260 } 21261 direct.add(e); 21262 } 21263 } 21264 } 21265 21266 private boolean isArrayAggRowReference(TObjectName on) { 21267 if (on == null) return false; 21268 TTable src = on.getSourceTable(); 21269 if (src == null) return false; 21270 21271 String nm = DlineageUtil.getColumnName(on); 21272 if (nm == null || nm.isEmpty()) return false; 21273 21274 // Check if identifier text matches the table alias or table name 21275 boolean matchesAlias = 21276 (src.getAliasName() != null 21277 && src.getAliasName().toString().equalsIgnoreCase(nm)) 21278 || (src.getTableName() != null 21279 && src.getTableName().toString().equalsIgnoreCase(nm)); 21280 return matchesAlias; 21281 } 21282 21283 /** 21284 * Collects column names inferred from a row-reference array_agg: 21285 * - ORDER BY keys inside the function call 21286 * - GROUP BY keys in the enclosing SELECT 21287 * Excludes the table alias itself (so `original` in `array_agg(original)` 21288 * does not leak into the column list). 21289 */ 21290 private List<TObjectName> collectRowReferenceInferredColumns( 21291 TFunctionCall functionCall, String tableAlias) { 21292 List<TObjectName> columns = new ArrayList<TObjectName>(); 21293 21294 TOrderByItemList orderItems = null; 21295 if (functionCall.getSortClause() != null) { 21296 orderItems = functionCall.getSortClause().getItems(); 21297 } 21298 if (orderItems == null || orderItems.size() == 0) { 21299 orderItems = functionCall.getOrderByList(); 21300 } 21301 if (orderItems != null) { 21302 for (int k = 0; k < orderItems.size(); k++) { 21303 TExpression sortKey = orderItems.getOrderByItem(k).getSortKey(); 21304 collectInferredColumn(sortKey, tableAlias, columns); 21305 } 21306 } 21307 21308 if (!stmtStack.isEmpty() && stmtStack.peek() instanceof TSelectSqlStatement) { 21309 TSelectSqlStatement select = (TSelectSqlStatement) stmtStack.peek(); 21310 if (select.getGroupByClause() != null) { 21311 TGroupByItemList groupByList = select.getGroupByClause().getItems(); 21312 for (int k = 0; k < groupByList.size(); k++) { 21313 TExpression expr = groupByList.getGroupByItem(k).getExpr(); 21314 collectInferredColumn(expr, tableAlias, columns); 21315 } 21316 } 21317 } 21318 return columns; 21319 } 21320 21321 private void collectInferredColumn(TExpression expr, String tableAlias, 21322 List<TObjectName> columns) { 21323 if (expr == null) return; 21324 if (expr.getExpressionType() != EExpressionType.simple_object_name_t) return; 21325 if (expr.getObjectOperand() == null) return; 21326 String colName = DlineageUtil.getColumnName(expr.getObjectOperand()); 21327 if (colName == null || colName.isEmpty()) return; 21328 if (tableAlias != null && tableAlias.equalsIgnoreCase(colName)) return; 21329 if(!columns.contains(expr.getObjectOperand())) { 21330 columns.add(expr.getObjectOperand()); 21331 } 21332 } 21333 21334 /** 21335 * Creates a `*` FunctionResultColumn plus one FunctionResultColumn per 21336 * inferred column. Each column gets its own source-edge back to 21337 * the source table (source.* -> function.*, source.id -> function.id, etc). 21338 * 21339 * Downstream, the `*` column collects all three edges into the inner 21340 * `unique` ResultColumn, and post-processing (rewriteArrayAggRowReferenceTargets) 21341 * splits the collapsed CTAS relation into one per column. 21342 */ 21343 private void createRowReferenceStarColumn(Function function, TTable src, 21344 List<TObjectName> inferredColumns) { 21345 Object tableModel = modelManager.getModel(src); 21346 21347 // Create function.* and bind source.* -> function.* 21348 TObjectName starName = new TObjectName(); 21349 starName.setString("*"); 21350 ResultColumn starColumn = modelFactory.createFunctionResultColumn(function, starName); 21351 starColumn.setStruct(true); 21352 starColumn.setShowStar(true); 21353 21354 if (tableModel instanceof Table) { 21355 Table sourceTable = (Table) tableModel; 21356 TableColumn sourceCol = findOrCreateTableColumn(sourceTable, "*"); 21357 21358 for (TObjectName colName : inferredColumns) { 21359 TableColumn tableColumn = modelFactory.createTableColumn(sourceTable, colName, false); 21360 if (tableColumn != null) { 21361 //order by and group by fdr relation 21362 AbstractRelationship relation = modelFactory.createImpactRelation(); 21363 relation.setEffectType(EffectType.function); 21364 relation.setTarget(new ResultColumnRelationshipElement(starColumn)); 21365 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 21366 21367 // star column fdd relation 21368 relation = modelFactory.createDataFlowRelation(); 21369 relation.setEffectType(EffectType.function); 21370 relation.setTarget(new ResultColumnRelationshipElement(starColumn)); 21371 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 21372 } 21373 } 21374 21375 21376 if (sourceCol != null) { 21377 DataFlowRelationship rel = modelFactory.createDataFlowRelation(); 21378 rel.setEffectType(EffectType.function); 21379 rel.setTarget(new ResultColumnRelationshipElement(starColumn)); 21380 rel.addSource(new TableColumnRelationshipElement(sourceCol)); 21381 } 21382 21383 } else if (tableModel instanceof ResultSet) { 21384 ResultSet sourceRS = (ResultSet) tableModel; 21385 ResultColumn sourceCol = findOrCreateResultColumn(sourceRS, "*"); 21386 for (TObjectName colName : inferredColumns) { 21387 sourceCol.bindStarLinkColumn(colName); 21388 } 21389 21390 if (sourceCol != null) { 21391 DataFlowRelationship rel = modelFactory.createDataFlowRelation(); 21392 rel.setEffectType(EffectType.function); 21393 rel.setTarget(new ResultColumnRelationshipElement(starColumn)); 21394 rel.addSource(new ResultColumnRelationshipElement(sourceCol)); 21395 } 21396 } 21397 } 21398 21399 /** 21400 * Builds the Function lineage model for a structured-dataflow descriptor. 21401 * Creates per-field FunctionResultColumns and links each to an exact 21402 * structured source TableColumn (e.g. {@code nodes[*].key}). Returns the 21403 * Function on success; returns {@code null} when the source column cannot 21404 * be resolved so the caller falls back to existing function lineage. 21405 */ 21406 private Function createStructuredDataflowFunction(StructuredDataflowDescriptor desc) { 21407 TParseTreeNode syntaxNode = desc.getSyntaxNode(); 21408 if (!(syntaxNode instanceof TFunctionCall)) { 21409 return null; 21410 } 21411 TFunctionCall fnCall = (TFunctionCall) syntaxNode; 21412 21413 Function function = null; 21414 Object existing = modelManager.getModel(fnCall); 21415 if (existing instanceof Function) { 21416 function = (Function) existing; 21417 } 21418 boolean alreadyBuilt = function != null 21419 && function.getColumns() != null 21420 && !function.getColumns().isEmpty(); 21421 if (alreadyBuilt) { 21422 return function; 21423 } 21424 if (function == null) { 21425 function = modelFactory.createFunction(fnCall); 21426 } 21427 21428 StructuredValueSource src = desc.getSource(); 21429 TObjectName sourceColumn = src.getSourceColumn(); 21430 TTable srcTable = sourceColumn != null ? sourceColumn.getSourceTable() : null; 21431 Object srcTableModel = srcTable != null ? modelManager.getModel(srcTable) : null; 21432 if (!(srcTableModel instanceof Table)) { 21433 return null; 21434 } 21435 Table sourceTable = (Table) srcTableModel; 21436 21437 for (StructuredFieldBinding fb : desc.getFieldBindings()) { 21438 String pathDisplay = fb.getSourcePath().toDisplayString(); 21439 TableColumn pathColumn = findOrCreateStructuredPathColumn(sourceTable, pathDisplay); 21440 if (pathColumn == null) { 21441 continue; 21442 } 21443 21444 TObjectName fieldName = new TObjectName(); 21445 fieldName.setString(fb.getOutputFieldName()); 21446 ResultColumn fnResult = modelFactory.createFunctionResultColumn(function, fieldName); 21447 21448 DataFlowRelationship rel = modelFactory.createDataFlowRelation(); 21449 rel.setEffectType(EffectType.function); 21450 rel.setTarget(new ResultColumnRelationshipElement(fnResult)); 21451 rel.addSource(new TableColumnRelationshipElement(pathColumn)); 21452 } 21453 return function; 21454 } 21455 21456 /** 21457 * Resolve a struct-field-style outer reference ({@code structAlias.field} 21458 * or {@code relAlias.structAlias.field}) against in-scope subquery 21459 * QueryTables that hold a struct-bearing result column. When found, 21460 * append a relation source pointing at the function's field result 21461 * column so the exact source path (e.g. {@code nodes[*].key}) is 21462 * preserved through the outer projection. Returns {@code true} when 21463 * the reference was bound and the caller should skip orphan-column 21464 * fallback. 21465 */ 21466 private boolean tryAppendStructuredFieldRelation(DataFlowRelationship relation, 21467 TObjectName columnName, TTableList tableList) { 21468 if (relation == null || columnName == null || tableList == null) { 21469 return false; 21470 } 21471 String fullText = columnName.toString(); 21472 if (fullText == null) return false; 21473 int firstDot = fullText.indexOf('.'); 21474 if (firstDot < 0) return false; 21475 21476 String structAlias; 21477 String fieldName; 21478 int lastDot = fullText.lastIndexOf('.'); 21479 if (firstDot == lastDot) { 21480 structAlias = fullText.substring(0, firstDot); 21481 fieldName = fullText.substring(firstDot + 1); 21482 } else { 21483 structAlias = fullText.substring(firstDot + 1, lastDot); 21484 fieldName = fullText.substring(lastDot + 1); 21485 } 21486 if (structAlias == null || structAlias.isEmpty()) return false; 21487 if (fieldName == null || fieldName.isEmpty()) return false; 21488 21489 for (int i = 0; i < tableList.size(); i++) { 21490 TTable tt = tableList.getTable(i); 21491 if (tt == null) continue; 21492 Object tm = modelManager.getModel(tt); 21493 if (!(tm instanceof QueryTable)) continue; 21494 QueryTable qt = (QueryTable) tm; 21495 if (qt.getColumns() == null) continue; 21496 for (ResultColumn rc : qt.getColumns()) { 21497 if (rc == null || rc.getName() == null) continue; 21498 if (!structAlias.equalsIgnoreCase(rc.getName())) continue; 21499 ResultColumn fieldColumn = findStructuredFieldColumn(rc, fieldName); 21500 if (fieldColumn != null) { 21501 relation.addSource(new ResultColumnRelationshipElement(fieldColumn)); 21502 return true; 21503 } 21504 } 21505 } 21506 return false; 21507 } 21508 21509 /** 21510 * Given a QueryTable result column that aliases a structured generator 21511 * (e.g. {@code nodes1} backed by Spark {@code explode(from_json(...))}), 21512 * locate the FunctionResultColumn named {@code fieldName}. The Function 21513 * model is discovered by walking the existing data-flow relations whose 21514 * target is the alias column. 21515 */ 21516 private ResultColumn findStructuredFieldColumn(ResultColumn aliasColumn, String fieldName) { 21517 if (aliasColumn == null || fieldName == null) return null; 21518 Relationship[] rels = modelManager.getRelations(); 21519 if (rels == null) return null; 21520 String normalField = fieldName.trim(); 21521 for (Relationship r : rels) { 21522 if (!(r instanceof DataFlowRelationship)) continue; 21523 DataFlowRelationship dfr = (DataFlowRelationship) r; 21524 if (dfr.getTarget() == null) continue; 21525 if (!(dfr.getTarget().getElement() == aliasColumn)) continue; 21526 if (dfr.getSources() == null) continue; 21527 for (RelationshipElement<?> se : dfr.getSources()) { 21528 Object srcElement = se.getElement(); 21529 if (!(srcElement instanceof ResultColumn)) continue; 21530 ResultColumn src = (ResultColumn) srcElement; 21531 if (normalField.equalsIgnoreCase(src.getName())) { 21532 return src; 21533 } 21534 } 21535 } 21536 return null; 21537 } 21538 21539 /** 21540 * Find-or-create a TableColumn carrying a structured display path 21541 * (e.g. {@code nodes[*].key}) on the given source table. Unlike the 21542 * standard {@link #findOrCreateTableColumn(Table, String)}, this does 21543 * not treat the dotted/bracketed text as a schema-qualified name; 21544 * the entire path is used as the column display, so existing flat 21545 * columns named after the leaf field (e.g. {@code key}) do not 21546 * collide with structured-path columns. 21547 */ 21548 private TableColumn findOrCreateStructuredPathColumn(Table table, String pathDisplay) { 21549 if (table == null || pathDisplay == null || pathDisplay.isEmpty()) return null; 21550 for (TableColumn tc : table.getColumns()) { 21551 if (pathDisplay.equalsIgnoreCase(tc.getName())) { 21552 return tc; 21553 } 21554 } 21555 return new TableColumn(table, pathDisplay); 21556 } 21557 21558 private TableColumn findOrCreateTableColumn(Table table, String colName) { 21559 String normalName = DlineageUtil.getIdentifierNormalColumnName(colName); 21560 for (TableColumn tc : table.getColumns()) { 21561 if ("*".equals(colName) && "*".equals(tc.getName())) return tc; 21562 if (DlineageUtil.compareColumnIdentifier(tc.getName(), normalName)) return tc; 21563 } 21564 TObjectName obj = new TObjectName(); 21565 obj.setString(colName); 21566 return modelFactory.createTableColumn(table, obj, "*".equals(colName)); 21567 } 21568 21569 private ResultColumn findOrCreateResultColumn(ResultSet resultSet, String colName) { 21570 String normalName = DlineageUtil.getIdentifierNormalColumnName(colName); 21571 for (ResultColumn rc : resultSet.getColumns()) { 21572 if ("*".equals(colName) && "*".equals(rc.getName())) return rc; 21573 if (DlineageUtil.compareColumnIdentifier(rc.getName(), normalName)) return rc; 21574 } 21575 TObjectName obj = new TObjectName(); 21576 obj.setString(colName); 21577 return modelFactory.createResultColumn(resultSet, obj); 21578 } 21579 21580 private void getFunctionExpressions(List<TExpression> directExpressions, List<TExpression> indirectExpressions, 21581 TFunctionCall functionCall) { 21582 if (functionCall.getArgs() != null) { 21583 for (int k = 0; k < functionCall.getArgs().size(); k++) { 21584 TExpression expr = functionCall.getArgs().getExpression(k); 21585 if(FunctionUtility.isDirectRelation(option.getVendor(), functionCall.getFunctionName().toString(), functionCall.getArgs().size(), k)) { 21586 directExpressions.add(expr); 21587 } 21588 if(FunctionUtility.isIndirectRelation(option.getVendor(), functionCall.getFunctionName().toString(), functionCall.getArgs().size(), k)) { 21589 if("DECODE".equalsIgnoreCase(functionCall.getFunctionName().toString()) && option.getVendor() == EDbVendor.dbvoracle) { 21590 if(option.isShowCaseWhenAsDirect()) { 21591 directExpressions.add(expr); 21592 continue; 21593 } 21594 } 21595 indirectExpressions.add(expr); 21596 } 21597 } 21598 } 21599 collectOracleXmlFunctionExpressions(functionCall, directExpressions, indirectExpressions); 21600 collectArrayAggOrderByExpressions(functionCall, directExpressions, indirectExpressions); 21601 if (functionCall.getTrimArgument() != null) { 21602 TTrimArgument args = functionCall.getTrimArgument(); 21603 TExpression expr = args.getStringExpression(); 21604 if (expr != null) { 21605 directExpressions.add(expr); 21606 } 21607 expr = args.getTrimCharacter(); 21608 if (expr != null) { 21609 directExpressions.add(expr); 21610 } 21611 } 21612 21613 if (functionCall.getAgainstExpr() != null) { 21614 directExpressions.add(functionCall.getAgainstExpr()); 21615 } 21616// if (functionCall.getBetweenExpr() != null) { 21617// directExpressions.add(functionCall.getBetweenExpr()); 21618// } 21619 if (functionCall.getExpr1() != null) { 21620 directExpressions.add(functionCall.getExpr1()); 21621 } 21622 if (functionCall.getExpr2() != null) { 21623 directExpressions.add(functionCall.getExpr2()); 21624 } 21625 if (functionCall.getExpr3() != null) { 21626 directExpressions.add(functionCall.getExpr3()); 21627 } 21628 if (functionCall.getParameter() != null) { 21629 directExpressions.add(functionCall.getParameter()); 21630 } 21631 if (functionCall.getWindowDef() != null && functionCall.getWindowDef().getPartitionClause() != null) { 21632 TExpressionList args = functionCall.getWindowDef().getPartitionClause().getExpressionList(); 21633 if (args != null) { 21634 for (int k = 0; k < args.size(); k++) { 21635 TExpression expr = args.getExpression(k); 21636 if (expr != null) { 21637 indirectExpressions.add(expr); 21638 } 21639 } 21640 } 21641 } 21642 if (functionCall.getWindowDef() != null && functionCall.getWindowDef().getOrderBy() != null) { 21643 TOrderByItemList orderByList = functionCall.getWindowDef().getOrderBy().getItems(); 21644 for (int i = 0; i < orderByList.size(); i++) { 21645 TOrderByItem element = orderByList.getOrderByItem(i); 21646 TExpression expression = element.getSortKey(); 21647 indirectExpressions.add(expression); 21648 } 21649 } 21650 if (functionCall.getWithinGroup() != null && functionCall.getWithinGroup().getOrderBy() != null) { 21651 TOrderByItemList orderByList = functionCall.getWithinGroup().getOrderBy().getItems(); 21652 for (int i = 0; i < orderByList.size(); i++) { 21653 TOrderByItem element = orderByList.getOrderByItem(i); 21654 TExpression expression = element.getSortKey(); 21655 indirectExpressions.add(expression); 21656 } 21657 } 21658 if (functionCall.getCallTarget() != null) { 21659 directExpressions.add(functionCall.getCallTarget().getExpr()); 21660 } 21661 if (functionCall.getFieldValues() != null) { 21662 for (int k = 0; k < functionCall.getFieldValues().size(); k++) { 21663 TExpression expr = functionCall.getFieldValues().getResultColumn(k).getExpr(); 21664 directExpressions.add(expr); 21665 } 21666 } 21667 if (functionCall instanceof TJsonObjectFunction) { 21668 TJsonObjectFunction jsonObject = (TJsonObjectFunction)functionCall; 21669 for (int k = 0; k < jsonObject.getKeyValues().size(); k++) { 21670 TExpression expr = jsonObject.getKeyValues().get(k).getValue(); 21671 directExpressions.add(expr); 21672 } 21673 } 21674 if (functionCall.getGroupConcatParam() != null) { 21675 for (int k = 0; k < functionCall.getGroupConcatParam().getExprList().size(); k++) { 21676 TExpression expr = functionCall.getGroupConcatParam().getExprList().getExpression(k); 21677 directExpressions.add(expr); 21678 } 21679 } 21680 } 21681 21682 private void getFunctionExpressions(List<TExpression> directExpressions, List<TExpression> indirectExpressions, 21683 TFunctionCall functionCall, int argumentIndex) { 21684 if (functionCall.getArgs() != null && argumentIndex < functionCall.getArgs().size()) { 21685 TExpression expr = functionCall.getArgs().getExpression(argumentIndex); 21686 if (FunctionUtility.isDirectRelation(option.getVendor(), functionCall.getFunctionName().toString(), functionCall.getArgs().size(), argumentIndex)) { 21687 directExpressions.add(expr); 21688 } 21689 if (FunctionUtility.isIndirectRelation(option.getVendor(), functionCall.getFunctionName().toString(), functionCall.getArgs().size(), argumentIndex)) { 21690 indirectExpressions.add(expr); 21691 } 21692 } 21693 } 21694 21695 private void getFunctionExpressions(List<TExpression> directExpressions, List<TExpression> indirectExpressions, 21696 TCallStatement functionCall, int argumentIndex) { 21697 if (functionCall.getArgs() != null && argumentIndex < functionCall.getArgs().size()) { 21698 TExpression expr = functionCall.getArgs().getExpression(argumentIndex); 21699 if (FunctionUtility.isDirectRelation(option.getVendor(), functionCall.getRoutineName().toString(), 21700 functionCall.getArgs().size(), argumentIndex)) { 21701 directExpressions.add(expr); 21702 } 21703 if (FunctionUtility.isIndirectRelation(option.getVendor(), functionCall.getRoutineName().toString(), 21704 functionCall.getArgs().size(), argumentIndex)) { 21705 indirectExpressions.add(expr); 21706 } 21707 } 21708 } 21709 21710 private void getFunctionExpressions(List<TExpression> directExpressions, List<TExpression> indirectExpressions, 21711 TDb2CallStmt functionCall, int argumentIndex) { 21712 if (functionCall.getParameters() != null && argumentIndex < functionCall.getParameters().size()) { 21713 TExpression expr = functionCall.getParameters().getExpression(argumentIndex); 21714 if (FunctionUtility.isDirectRelation(option.getVendor(), functionCall.getProcedureName().toString(), 21715 functionCall.getParameters().size(), argumentIndex)) { 21716 directExpressions.add(expr); 21717 } 21718 if (FunctionUtility.isIndirectRelation(option.getVendor(), functionCall.getProcedureName().toString(), 21719 functionCall.getParameters().size(), argumentIndex)) { 21720 indirectExpressions.add(expr); 21721 } 21722 } 21723 } 21724 21725 private void getFunctionExpressions(List<TExpression> directExpressions, List<TExpression> indirectExpressions, 21726 TMssqlExecute functionCall, String argumentName, int argumentIndex) { 21727 if (functionCall.getParameters() != null) { 21728 for (int i = 0; i < functionCall.getParameters().size(); i++) { 21729 TExecParameter param = functionCall.getParameters().getExecParameter(i); 21730 if (param.getParameterName() != null) { 21731 if (DlineageUtil.compareColumnIdentifier(param.getParameterName().toString(), argumentName)) { 21732 TExpression expr = param.getParameterValue(); 21733 directExpressions.add(expr); 21734 } 21735 } else if (i == argumentIndex) { 21736 TExpression expr = param.getParameterValue(); 21737 directExpressions.add(expr); 21738 } 21739 } 21740 } 21741 } 21742 21743 private void analyzeJoin(TJoin join, EffectType effectType) { 21744 if (join.getJoinItems() != null) { 21745 for (int j = 0; j < join.getJoinItems().size(); j++) { 21746 TJoinItem joinItem = join.getJoinItems().getJoinItem(j); 21747 TExpression expr = joinItem.getOnCondition(); 21748 if (expr != null) { 21749 analyzeFilterCondition(null, expr, joinItem.getJoinType(), JoinClauseType.on, effectType); 21750 } 21751 } 21752 } 21753 21754 if (join.getJoin() != null) { 21755 analyzeJoin(join.getJoin(), effectType); 21756 } 21757 } 21758 21759 private TSelectSqlStatement getParentSetSelectStmt(TSelectSqlStatement stmt) { 21760 TCustomSqlStatement parent = stmt.getParentStmt(); 21761 if (parent == null) 21762 return null; 21763 if (parent.getStatements() != null) { 21764 for (int i = 0; i < parent.getStatements().size(); i++) { 21765 TCustomSqlStatement temp = parent.getStatements().get(i); 21766 if (temp instanceof TSelectSqlStatement) { 21767 TSelectSqlStatement select = (TSelectSqlStatement) temp; 21768 if (select.getLeftStmt() == stmt || select.getRightStmt() == stmt) 21769 return select; 21770 } 21771 } 21772 } 21773 if (parent instanceof TSelectSqlStatement) { 21774 TSelectSqlStatement select = (TSelectSqlStatement) parent; 21775 if (select.getLeftStmt() == stmt || select.getRightStmt() == stmt) 21776 return select; 21777 } 21778 return null; 21779 } 21780 21781 private void createSelectSetResultColumns(SelectSetResultSet resultSet, TSelectSqlStatement stmt) { 21782 if (stmt.getSetOperatorType() != ESetOperatorType.none) { 21783 createSelectSetResultColumns(resultSet, stmt.getLeftStmt()); 21784 } else { 21785 TResultColumnList columnList = stmt.getResultColumnList(); 21786 ResultSet subqueryResultSet = (ResultSet) modelManager.getModel(columnList); 21787 if(subqueryResultSet!=null && subqueryResultSet.isDetermined()) { 21788 for (int j = 0; j < subqueryResultSet.getColumns().size(); j++) { 21789 ResultColumn tableColumn = subqueryResultSet.getColumns().get(j); 21790 if (tableColumn.getRefColumnName() != null) { 21791 TObjectName columnName = new TObjectName(); 21792 columnName.setString(tableColumn.getRefColumnName()); 21793 modelFactory.createDeterminedResultColumn( 21794 resultSet, columnName); 21795 } else { 21796 TObjectName columnName = new TObjectName(); 21797 columnName.setString(tableColumn.getName()); 21798 modelFactory.createDeterminedResultColumn( 21799 resultSet, columnName); 21800 } 21801 } 21802 resultSet.setDetermined(true); 21803 return; 21804 } 21805 21806 boolean isDetermined = true; 21807 for (int i = 0; i < columnList.size(); i++) { 21808 TResultColumn column = columnList.getResultColumn(i); 21809 21810 if ("*".equals(column.getColumnNameOnly())) { 21811 TObjectName columnObject = column.getFieldAttr(); 21812 TTable sourceTable = columnObject.getSourceTable(); 21813 if (sourceTable != null) { 21814 Object tableModel = modelManager.getModel(sourceTable); 21815 if (tableModel instanceof Table && ((Table) tableModel).isCreateTable()) { 21816 Table table = (Table) tableModel; 21817 for (int j = 0; j < table.getColumns().size(); j++) { 21818 TableColumn tableColumn = table.getColumns().get(j); 21819 if (column.getExceptColumnList() != null) { 21820 boolean except = false; 21821 for (TObjectName objectName : column.getExceptColumnList()) { 21822 if (getColumnName(objectName.toString()) 21823 .equals(getColumnName(tableColumn.getName()))) { 21824 except = true; 21825 break; 21826 } 21827 } 21828 if (!except && tableColumn.isStruct()) { 21829 List<String> names = SQLUtil 21830 .parseNames(tableColumn.getName()); 21831 for (String name : names) { 21832 for (TObjectName objectName : column 21833 .getExceptColumnList()) { 21834 if (getColumnName(objectName.toString()) 21835 .equals(getColumnName(name))) { 21836 except = true; 21837 break; 21838 } 21839 } 21840 if (except) { 21841 break; 21842 } 21843 } 21844 } 21845 if (except) { 21846 continue; 21847 } 21848 } 21849 TObjectName columnName = new TObjectName(); 21850 columnName.setString(tableColumn.getName()); 21851 ResultColumn resultColumn = modelFactory.createResultColumn( 21852 resultSet, columnName); 21853 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 21854 relation.setEffectType(EffectType.select); 21855 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 21856 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 21857 } 21858 continue; 21859 } else if (tableModel instanceof ResultSet 21860 && ((ResultSet) tableModel).isDetermined()) { 21861 ResultSet table = (ResultSet) tableModel; 21862 for (int j = 0; j < table.getColumns().size(); j++) { 21863 ResultColumn tableColumn = table.getColumns().get(j); 21864 if (column.getExceptColumnList() != null) { 21865 boolean except = false; 21866 for (TObjectName objectName : column.getExceptColumnList()) { 21867 if (getColumnName(objectName.toString()) 21868 .equals(getColumnName(tableColumn.getName()))) { 21869 except = true; 21870 break; 21871 } 21872 } 21873 if (!except && tableColumn.isStruct()) { 21874 List<String> names = SQLUtil 21875 .parseNames(tableColumn.getName()); 21876 for (String name : names) { 21877 for (TObjectName objectName : column 21878 .getExceptColumnList()) { 21879 if (getColumnName(objectName.toString()) 21880 .equals(getColumnName(name))) { 21881 except = true; 21882 break; 21883 } 21884 } 21885 if (except) { 21886 break; 21887 } 21888 } 21889 } 21890 if (except) { 21891 continue; 21892 } 21893 } 21894 if (tableColumn.getRefColumnName() != null) { 21895 TObjectName columnName = new TObjectName(); 21896 columnName.setString(tableColumn.getRefColumnName()); 21897 ResultColumn resultColumn = modelFactory.createResultColumn( 21898 resultSet, columnName); 21899 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 21900 relation.setEffectType(EffectType.select); 21901 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 21902 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 21903 } else { 21904 TObjectName columnName = new TObjectName(); 21905 columnName.setString(tableColumn.getName()); 21906 ResultColumn resultColumn = modelFactory.createResultColumn( 21907 resultSet, columnName); 21908 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 21909 relation.setEffectType(EffectType.select); 21910 relation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 21911 relation.addSource(new ResultColumnRelationshipElement(tableColumn)); 21912 } 21913 } 21914 continue; 21915 } 21916 else { 21917 isDetermined = false; 21918 } 21919 } 21920 } 21921 21922 ResultColumn resultColumn = modelFactory.createSelectSetResultColumn(resultSet, column, i); 21923 21924 if (resultColumn.getColumnObject() instanceof TResultColumn) { 21925 TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject(); 21926 if (columnObject.getFieldAttr() != null) { 21927 if ("*".equals(getColumnName(columnObject.getFieldAttr()))) { 21928 TObjectName fieldAttr = columnObject.getFieldAttr(); 21929 TTable sourceTable = fieldAttr.getSourceTable(); 21930 if (fieldAttr.getTableToken() != null && sourceTable != null) { 21931 TObjectName[] columns = modelManager.getTableColumns(sourceTable); 21932 for (int j = 0; j < columns.length; j++) { 21933 TObjectName columnName = columns[j]; 21934 if (columnName == null) { 21935 continue; 21936 } 21937 if ("*".equals(getColumnName(columnName))) { 21938 continue; 21939 } 21940 resultColumn.bindStarLinkColumn(columnName); 21941 } 21942 21943 if (modelManager.getModel(sourceTable) instanceof Table) { 21944 Table tableModel = (Table) modelManager.getModel(sourceTable); 21945 if (tableModel != null && !tableModel.getColumns().isEmpty()) { 21946 for (int z = 0; z < tableModel.getColumns().size(); z++) { 21947 if ("*".equals( 21948 getColumnName(tableModel.getColumns().get(z).getColumnObject()))) { 21949 continue; 21950 } 21951 resultColumn.bindStarLinkColumn( 21952 tableModel.getColumns().get(z).getColumnObject()); 21953 } 21954 } 21955 } else if (modelManager.getModel(sourceTable) instanceof QueryTable) { 21956 QueryTable tableModel = (QueryTable) modelManager.getModel(sourceTable); 21957 if (tableModel != null && !tableModel.getColumns().isEmpty()) { 21958 for (ResultColumn item : tableModel.getColumns()) { 21959 if (item.hasStarLinkColumn()) { 21960 for (TObjectName starLinkColumn : item.getStarLinkColumnList()) { 21961 if ("*".equals(getColumnName(starLinkColumn))) { 21962 continue; 21963 } 21964 resultColumn.bindStarLinkColumn(starLinkColumn); 21965 } 21966 } else if (item.getColumnObject() instanceof TObjectName) { 21967 TObjectName starLinkColumn = (TObjectName) item.getColumnObject(); 21968 if ("*".equals(getColumnName(starLinkColumn))) { 21969 continue; 21970 } 21971 resultColumn.bindStarLinkColumn(starLinkColumn); 21972 } 21973 } 21974 } 21975 } 21976 21977 } else { 21978 TTableList tables = stmt.getTables(); 21979 for (int k = 0; k < tables.size(); k++) { 21980 TTable tableElement = tables.getTable(k); 21981 TObjectName[] columns = modelManager.getTableColumns(tableElement); 21982 for (int j = 0; j < columns.length; j++) { 21983 TObjectName columnName = columns[j]; 21984 if (columnName == null) { 21985 continue; 21986 } 21987 if ("*".equals(getColumnName(columnName))) { 21988 if (modelManager.getModel(tableElement) instanceof Table) { 21989 Table tableModel = (Table) modelManager.getModel(tableElement); 21990 if (tableModel != null && !tableModel.getColumns().isEmpty()) { 21991 for (int z = 0; z < tableModel.getColumns().size(); z++) { 21992 resultColumn.bindStarLinkColumn( 21993 tableModel.getColumns().get(z).getColumnObject()); 21994 } 21995 } 21996 } else if (modelManager.getModel(tableElement) instanceof QueryTable) { 21997 QueryTable tableModel = (QueryTable) modelManager 21998 .getModel(tableElement); 21999 if (tableModel != null && !tableModel.getColumns().isEmpty()) { 22000 for (ResultColumn item : tableModel.getColumns()) { 22001 if (item.hasStarLinkColumn()) { 22002 for (TObjectName starLinkColumn : item 22003 .getStarLinkColumnList()) { 22004 resultColumn.bindStarLinkColumn(starLinkColumn); 22005 } 22006 } else if (item.getColumnObject() instanceof TObjectName) { 22007 resultColumn.bindStarLinkColumn( 22008 (TObjectName) item.getColumnObject()); 22009 } 22010 } 22011 } 22012 } 22013 continue; 22014 } 22015 resultColumn.bindStarLinkColumn(columnName); 22016 } 22017 } 22018 } 22019 } 22020 } 22021 } 22022 22023 resultSet.setDetermined(isDetermined); 22024 } 22025 } 22026 } 22027 22028 private void analyzeResultColumn(TResultColumn column, EffectType effectType) { 22029 // A SELECT * star column whose source resolves to a determined result set 22030 // is bound to a LinkedHashMap of per-column ResultColumns (see 22031 // ModelFactory.createStarResultColumn), and its data-flow relationships 22032 // are already created inline during star expansion in analyzeSelectStmt(). 22033 // Re-analyzing the raw "*" here is redundant; skip it. (analyzeDataFlowRelation 22034 // keeps the same guard as a defensive backstop.) 22035 if (modelManager.getModel(column) instanceof LinkedHashMap) { 22036 return; 22037 } 22038 TExpression expression = column.getExpr(); 22039 if (expression.getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) { 22040 expression = expression.getRightOperand(); 22041 } 22042 22043 if (expression.getExpressionType() == EExpressionType.array_t) { 22044 if (expression.getExprList() != null) { 22045 for (TExpression expr : expression.getExprList()) { 22046 columnsInExpr visitor = new columnsInExpr(); 22047 expr.inOrderTraverse(visitor); 22048 List<TObjectName> objectNames = visitor.getObjectNames(); 22049 22050 List<TParseTreeNode> functions = visitor.getFunctions(); 22051 22052 if (functions != null && !functions.isEmpty()) { 22053 analyzeFunctionDataFlowRelation(column, functions, effectType); 22054 } 22055 22056 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 22057 if (subquerys != null && !subquerys.isEmpty()) { 22058 analyzeSubqueryDataFlowRelation(column, subquerys, effectType); 22059 } 22060 22061 analyzeDataFlowRelation(column, objectNames, column.getExceptColumnList(), effectType, functions); 22062 22063 List<TParseTreeNode> constants = visitor.getConstants(); 22064 Object columnObject = modelManager.getModel(column); 22065 analyzeConstantDataFlowRelation(columnObject, constants, effectType, functions); 22066 22067 analyzeRecordSetRelation(functions, effectType); 22068 // analyzeResultColumnImpact( column, effectType, functions); 22069 } 22070 } 22071 else { 22072 List<TParseTreeNode> constants = new ArrayList<TParseTreeNode>(); 22073 TConstant constant = new TConstant(); 22074 constant.setString(expression.toString()); 22075 constants.add(constant); 22076 Object columnObject = modelManager.getModel(column); 22077 analyzeConstantDataFlowRelation(columnObject, constants, effectType, null); 22078 } 22079 } else { 22080 columnsInExpr visitor = new columnsInExpr(); 22081 expression.inOrderTraverse(visitor); 22082 List<TObjectName> objectNames = visitor.getObjectNames(); 22083 22084 List<TParseTreeNode> functions = visitor.getFunctions(); 22085 22086 if (functions != null && !functions.isEmpty()) { 22087 analyzeFunctionDataFlowRelation(column, functions, effectType); 22088 } 22089 22090 List<TSelectSqlStatement> subquerys = visitor.getSubquerys(); 22091 if (subquerys != null && !subquerys.isEmpty()) { 22092 analyzeSubqueryDataFlowRelation(column, subquerys, effectType); 22093 } 22094 22095 analyzeDataFlowRelation(column, objectNames, column.getExceptColumnList(), effectType, functions); 22096 22097 List<TParseTreeNode> constants = visitor.getConstants(); 22098 Object columnObject = modelManager.getModel(column); 22099 analyzeConstantDataFlowRelation(columnObject, constants, effectType, functions); 22100 22101 analyzeRecordSetRelation(functions, effectType); 22102 // analyzeResultColumnImpact( column, effectType, functions); 22103 } 22104 } 22105 22106 22107 private void analyzeValueColumn(Object object, TResultColumn column, EffectType effectType) { 22108 TExpression expression = column.getExpr(); 22109 if (expression.getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) { 22110 expression = expression.getRightOperand(); 22111 } 22112 22113 if (expression.getExpressionType() == EExpressionType.array_t) { 22114 if (expression.getExprList() != null) { 22115 for (TExpression expr : expression.getExprList()) { 22116 columnsInExpr visitor = new columnsInExpr(); 22117 expr.inOrderTraverse(visitor); 22118 List<TObjectName> objectNames = visitor.getObjectNames(); 22119 analyzeDataFlowRelation(object, objectNames, column.getExceptColumnList(), effectType, null, null); 22120 List<TParseTreeNode> constants = visitor.getConstants(); 22121 analyzeConstantDataFlowRelation(object, constants, effectType, null); 22122 } 22123 } 22124 else { 22125 List<TParseTreeNode> constants = new ArrayList<TParseTreeNode>(); 22126 TConstant constant = new TConstant(); 22127 constant.setString(expression.toString()); 22128 constants.add(constant); 22129 Object columnObject = modelManager.getModel(column); 22130 analyzeConstantDataFlowRelation(object, constants, effectType, null); 22131 } 22132 } else { 22133 columnsInExpr visitor = new columnsInExpr(); 22134 expression.inOrderTraverse(visitor); 22135 List<TObjectName> objectNames = visitor.getObjectNames(); 22136 analyzeDataFlowRelation(object, objectNames, column.getExceptColumnList(), effectType, null, null); 22137 List<TParseTreeNode> constants = visitor.getConstants(); 22138 analyzeConstantDataFlowRelation(object, constants, effectType, null); } 22139 } 22140 22141 private void analyzeTableColumn(TableColumn tableColumn, TFunctionCall functionCall, EffectType effectType) { 22142 List<TParseTreeNode> functions = new ArrayList<TParseTreeNode>(); 22143 functions.add(functionCall); 22144 22145 if (functions != null && !functions.isEmpty()) { 22146 analyzeFunctionDataFlowRelation(tableColumn, functions, effectType); 22147 } 22148 22149 analyzeRecordSetRelation(functions, effectType); 22150 } 22151 22152 private void analyzeRecordSetRelation(List<TParseTreeNode> functions, EffectType effectType) { 22153 if (functions == null || functions.size() == 0) 22154 return; 22155 22156 List<TFunctionCall> aggregateFunctions = new ArrayList<TFunctionCall>(); 22157 for (TParseTreeNode function : functions) { 22158 if (function instanceof TFunctionCall && isAggregateFunction((TFunctionCall) function)) { 22159 aggregateFunctions.add((TFunctionCall) function); 22160 } 22161 } 22162 22163 if (aggregateFunctions.size() == 0) 22164 return; 22165 22166 for (int i = 0; i < aggregateFunctions.size(); i++) { 22167 TFunctionCall function = aggregateFunctions.get(i); 22168 22169 TCustomSqlStatement stmt = stmtStack.peek(); 22170 if (stmt instanceof TSelectSqlStatement) { 22171 TSelectSqlStatement select = (TSelectSqlStatement) stmt; 22172 if (select.getGroupByClause() != null) { 22173 if (select.getGroupByClause().isAllModifier()) { 22174 // GROUP BY ALL: implicit grouping columns are the 22175 // non-aggregate expressions in the SELECT list. 22176 TResultColumnList resultColumns = select.getResultColumnList(); 22177 if (resultColumns != null) { 22178 for (int j = 0; j < resultColumns.size(); j++) { 22179 TResultColumn column = resultColumns.getResultColumn(j); 22180 TExpression expr = column.getExpr(); 22181 if (expr == null) 22182 continue; 22183 columnsInExpr aggVisitor = new columnsInExpr(); 22184 expr.inOrderTraverse(aggVisitor); 22185 boolean containsAggregate = false; 22186 for (TParseTreeNode funcNode : aggVisitor.getFunctions()) { 22187 if (funcNode instanceof TFunctionCall 22188 && isAggregateFunction((TFunctionCall) funcNode)) { 22189 containsAggregate = true; 22190 break; 22191 } 22192 } 22193 if (!containsAggregate) { 22194 analyzeAggregate(function, expr); 22195 } 22196 } 22197 } 22198 } else { 22199 TGroupByItemList groupByList = select.getGroupByClause().getItems(); 22200 for (int j = 0; j < groupByList.size(); j++) { 22201 TGroupByItem groupBy = groupByList.getGroupByItem(j); 22202 TExpression expr = groupBy.getExpr(); 22203 analyzeAggregate(function, expr); 22204 } 22205 } 22206 22207 if (select.getGroupByClause().getHavingClause() != null) { 22208 analyzeAggregate(function, select.getGroupByClause().getHavingClause()); 22209 } 22210 // if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString())) 22211 { 22212 analyzeAggregate(function, null); 22213 } 22214 } else { 22215 analyzeAggregate(function, null); 22216 } 22217 } 22218 } 22219 } 22220 22221 private void analyzeDataFlowRelation(TParseTreeNode gspObject, List<TObjectName> objectNames, 22222 TObjectNameList exceptColumnList, EffectType effectType, List<TParseTreeNode> functions) { 22223 Object columnObject = modelManager.getModel(gspObject); 22224 analyzeDataFlowRelation(columnObject, objectNames, exceptColumnList, effectType, functions, null); 22225 } 22226 22227 private DataFlowRelationship analyzeDataFlowRelation(Object modelObject, List<TObjectName> objectNames, EffectType effectType, 22228 List<TParseTreeNode> functions) { 22229 return analyzeDataFlowRelation(modelObject, objectNames, null, effectType, functions, null); 22230 } 22231 22232 private DataFlowRelationship analyzeDataFlowRelation(Object modelObject, List<TObjectName> objectNames, EffectType effectType, 22233 List<TParseTreeNode> functions, Process process) { 22234 return analyzeDataFlowRelation(modelObject, objectNames, null, effectType, functions, process); 22235 } 22236 22237 private DataFlowRelationship analyzeDataFlowRelation(Object modelObject, List<TObjectName> objectNames, 22238 TObjectNameList exceptColumnList, EffectType effectType, List<TParseTreeNode> functions, Process process) { 22239 return analyzeDataFlowRelation(modelObject, objectNames, exceptColumnList, effectType, functions, process, null); 22240 } 22241 22242 private DataFlowRelationship analyzeDataFlowRelation(Object modelObject, List<TObjectName> objectNames, 22243 TObjectNameList exceptColumnList, EffectType effectType, List<TParseTreeNode> functions, Process process, Integer valueIndex) { 22244 if (objectNames == null || objectNames.size() == 0) 22245 return null; 22246 22247 // Reject model objects this method cannot turn into a relationship BEFORE 22248 // creating one, since createDataFlowRelation() registers the relation 22249 // globally and an early return afterwards would leak an empty relation. 22250 // 22251 // - LinkedHashMap: a SELECT * star column whose source resolves to a 22252 // determined result set is expanded into per-column ResultColumns held 22253 // in a LinkedHashMap by ModelFactory.createStarResultColumn(), with its 22254 // data-flow relationships created inline during star expansion in 22255 // analyzeSelectStmt(). Re-analyzing the raw "*" here is a no-op. 22256 // - null: modelManager.getModel() found no binding for the gsp object. 22257 if (modelObject == null || modelObject instanceof LinkedHashMap) { 22258 return null; 22259 } 22260 // Lineage is best-effort: an unexpected model type should not abort the 22261 // whole statement's lineage (this used to throw UnsupportedOperationException). 22262 // Log it for diagnosis and skip just this column instead. 22263 if (!(modelObject instanceof ResultColumn) && !(modelObject instanceof TableColumn)) { 22264 logger.warn("analyzeDataFlowRelation: unhandled model type " 22265 + modelObject.getClass().getName() + ", effectType=" + effectType); 22266 return null; 22267 } 22268 22269 boolean isStar = false; 22270 boolean showStar = false; 22271 22272 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 22273 relation.setEffectType(effectType); 22274 relation.setProcess(process); 22275 22276 if (functions != null && !functions.isEmpty()) { 22277 relation.setFunction(getFunctionName(functions.get(0))); 22278 } 22279 22280 int columnIndex = -1; 22281 22282 boolean isOut = false; 22283 22284 if (modelObject instanceof ResultColumn) { 22285 relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) modelObject)); 22286 22287 if ("*".equals(((ResultColumn) modelObject).getName())) { 22288 isStar = true; 22289 showStar = ((ResultColumn) modelObject).isShowStar(); 22290 } 22291 22292 if (((ResultColumn) modelObject).getResultSet() != null) { 22293 columnIndex = ((ResultColumn) modelObject).getResultSet().getColumns().indexOf(modelObject); 22294 } 22295 } else if (modelObject instanceof TableColumn) { 22296 Table table = ((TableColumn) modelObject).getTable(); 22297 if(table.getSubType() == SubType.out && isNotInProcedure(table)){ 22298 isOut = true; 22299 relation.addSource(new TableColumnRelationshipElement((TableColumn) modelObject)); 22300 } 22301 else { 22302 relation.setTarget(new TableColumnRelationshipElement((TableColumn) modelObject)); 22303 } 22304 22305 if ("*".equals(((TableColumn) modelObject).getName())) { 22306 isStar = true; 22307 } 22308 22309 if (((TableColumn) modelObject).getTable() != null) { 22310 columnIndex = ((TableColumn) modelObject).getTable().getColumns().indexOf(modelObject); 22311 } 22312 } 22313 // No trailing else: modelObject is guaranteed to be a ResultColumn or 22314 // TableColumn here (validated and logged above before relation creation). 22315 22316 for (int i = 0; i < objectNames.size(); i++) { 22317 TObjectName columnName = objectNames.get(i); 22318 if (columnName.toString().indexOf(".") == -1 && isConstant(columnName)) { 22319 boolean isConstant = true; 22320 if (columnName.getSourceTable() != null) { 22321 Table tableModel = modelManager.getTableByName( 22322 DlineageUtil.getTableFullName(columnName.getSourceTable().getTableName().toString())); 22323 if (tableModel != null && tableModel.getColumns() != null) { 22324 for (int j = 0; j < tableModel.getColumns().size(); j++) { 22325 if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName), 22326 getColumnName(tableModel.getColumns().get(j).getName()))) { 22327 isConstant = false; 22328 break; 22329 } 22330 } 22331 } 22332 } 22333 22334 if (isConstant) { 22335 if (option.isShowConstantTable()) { 22336 Table constantTable = modelFactory.createConstantsTable(stmtStack.peek()); 22337 TableColumn tableColumn = modelFactory.createTableColumn(constantTable, columnName, false); 22338 if(tableColumn!=null) { 22339 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 22340 } 22341 } 22342 continue; 22343 } 22344 } 22345 if (columnName.getDbObjectType() == EDbObjectType.variable) { 22346 boolean find = false; 22347 List<String> segments = SQLUtil.parseNames(columnName.toString()); 22348 if (segments.size() == 1) { 22349 Table variable = modelManager.getTableByName(DlineageUtil.getTableFullName(columnName.toString())); 22350 if (variable != null) { 22351 TableColumn columnModel = variable.getColumns().get(0); 22352 if(variable.getColumns().size()>0){ 22353 TableColumn matchColumn = matchColumn(variable.getColumns(), columnName); 22354 if(matchColumn!=null){ 22355 columnModel = matchColumn; 22356 } 22357 } 22358 if(isOut){ 22359 relation.setTarget(new TableColumnRelationshipElement(columnModel)); 22360 } 22361 else { 22362 relation.addSource(new TableColumnRelationshipElement(columnModel)); 22363 } 22364 find = true; 22365 } else { 22366 if (columnName.toString().matches("\\$\\d+")) { 22367 TCustomSqlStatement stmt = stmtStack.peek(); 22368 Procedure procedure = modelManager 22369 .getProcedureByName(DlineageUtil.getTableFullName(getProcedureParentName(stmt))); 22370 if(procedure!=null) { 22371 Variable cursorVariable = modelFactory.createVariable(procedure.getArguments().get(Integer.valueOf(columnName.toString().replace("$", "")) - 1).getName()); 22372 if (isOut) { 22373 relation.setTarget(new TableColumnRelationshipElement(cursorVariable.getColumns().get(0))); 22374 } else { 22375 relation.addSource(new TableColumnRelationshipElement(cursorVariable.getColumns().get(0))); 22376 } 22377 } 22378 } else { 22379 Variable cursorVariable = modelFactory.createVariable(columnName); 22380 cursorVariable.setCreateTable(true); 22381 cursorVariable.setSubType(SubType.record); 22382 TableColumn variableProperty = null; 22383 if(cursorVariable.getColumns() == null || cursorVariable.getColumns().isEmpty()) { 22384 variableProperty = modelFactory.createTableColumn(cursorVariable, columnName, 22385 true); 22386 } 22387 else{ 22388 variableProperty = cursorVariable.getColumns().get(0); 22389 } 22390 if (isOut) { 22391 relation.setTarget(new TableColumnRelationshipElement(variableProperty)); 22392 } else { 22393 relation.addSource(new TableColumnRelationshipElement(variableProperty)); 22394 } 22395 } 22396 find = true; 22397 } 22398 } else if (option.getVendor() == EDbVendor.dbvoracle && columnName.getTableToken()!=null) { 22399 Variable cursorVariable = modelFactory 22400 .createVariable(columnName.getTableToken().toString()); 22401 22402 TObjectName variableColumnName = new TObjectName(); 22403 variableColumnName.setString(segments.get(segments.size() - 1)); 22404 22405 if (cursorVariable.getColumns() != null) { 22406 for (int j = 0; j < cursorVariable.getColumns().size(); j++) { 22407 if (getColumnName(variableColumnName) 22408 .equals(getColumnName(cursorVariable.getColumns().get(j).getColumnObject()))) { 22409 TableColumn columnModel = cursorVariable.getColumns().get(j); 22410 if (isOut) { 22411 relation.setTarget(new TableColumnRelationshipElement(columnModel)); 22412 } else { 22413 relation.addSource(new TableColumnRelationshipElement(columnModel)); 22414 } 22415 find = true; 22416 } 22417 } 22418 } 22419 22420 if (!find) { 22421 TableColumn variableColumn = new TableColumn(cursorVariable, variableColumnName); 22422 cursorVariable.addColumn(variableColumn); 22423 if (isOut) { 22424 relation.setTarget(new TableColumnRelationshipElement(variableColumn)); 22425 } else { 22426 relation.addSource(new TableColumnRelationshipElement(variableColumn)); 22427 } 22428 } 22429 } else { 22430 Table variable = modelManager 22431 .getTableByName(DlineageUtil.getTableFullName(segments.get(segments.size() - 2))); 22432 if (variable != null) { 22433 for (int j = 0; j < variable.getColumns().size(); j++) { 22434 if (getColumnName(columnName) 22435 .equals(getColumnName(variable.getColumns().get(j).getColumnObject()))) { 22436 TableColumn columnModel = variable.getColumns().get(j); 22437 if (isOut) { 22438 relation.setTarget(new TableColumnRelationshipElement(columnModel)); 22439 } else { 22440 relation.addSource(new TableColumnRelationshipElement(columnModel)); 22441 } 22442 find = true; 22443 } 22444 } 22445 } 22446 } 22447 if (!find) { 22448 TCustomSqlStatement stmt = stmtStack.peek(); 22449 if (getProcedureParentName(stmt) != null) { 22450 Procedure procedure = modelManager 22451 .getProcedureByName(DlineageUtil.getTableFullName(getProcedureParentName(stmt))); 22452 if (procedure != null && procedure.getArguments() != null) { 22453 for (Argument argument : procedure.getArguments()) { 22454 if (DlineageUtil.getTableFullName(argument.getName()) 22455 .equals(DlineageUtil.getTableFullName(columnName.toString()))) { 22456 relation.addSource(new ArgumentRelationshipElement(argument)); 22457 } 22458 } 22459 } 22460 } 22461 } 22462 continue; 22463 } 22464 22465 // Handle sequence pseudocolumn syntax (sequence.NEXTVAL or sequence.CURRVAL) 22466 // Used by Oracle, Snowflake, and accepted by other vendors for compatibility 22467 if(("NEXTVAL".equalsIgnoreCase(columnName.getColumnNameOnly()) || "CURRVAL".equalsIgnoreCase(columnName.getColumnNameOnly()))){ 22468 List<String> segments = SQLUtil.parseNames(columnName.toString()); 22469 if (segments.size() > 1) { 22470 segments.remove(segments.size()-1); 22471 Table table = modelFactory.createTableByName(SQLUtil.mergeSegments(segments, 0), true); 22472 table.setSequence(true); 22473 TableColumn seqCursor = modelFactory.createTableColumn(table, columnName, true); 22474 relation.addSource(new TableColumnRelationshipElement(seqCursor)); 22475 continue; 22476 } 22477 } 22478 22479 { 22480 if (columnName.getSourceTable() != null) { 22481 22482 } 22483 else { 22484 Table variable = modelManager.getTableByName(DlineageUtil.getTableFullName(columnName.toString())); 22485 if (variable == null) { 22486 variable = modelManager 22487 .getTableByName(DlineageUtil.getTableFullName(columnName.getTableString())); 22488 if (variable != null && variable.isCursor()) { 22489 TableColumn variableColumn = modelFactory.createInsertTableColumn(variable, columnName); 22490 if (variableColumn != null) { 22491 if(isOut){ 22492 relation.setTarget(new TableColumnRelationshipElement(variableColumn)); 22493 } 22494 else { 22495 relation.addSource(new TableColumnRelationshipElement(variableColumn)); 22496 } 22497 } else { 22498 if(isOut){ 22499 relation.setTarget(new TableColumnRelationshipElement(variable.getColumns().get(0))); 22500 } 22501 else { 22502 relation.addSource(new TableColumnRelationshipElement(variable.getColumns().get(0))); 22503 } 22504 } 22505 continue; 22506 } 22507 } else if (variable.isVariable() || variable.isCursor()) { 22508 TableColumn columnModel = variable.getColumns().get(0); 22509 if (valueIndex != null) { 22510 if(isOut){ 22511 relation.setTarget(new TableColumnRelationshipElement(columnModel, valueIndex)); 22512 } 22513 else { 22514 relation.addSource(new TableColumnRelationshipElement(columnModel, valueIndex)); 22515 } 22516 } else { 22517 if(isOut){ 22518 relation.setTarget(new TableColumnRelationshipElement(columnModel)); 22519 } 22520 else { 22521 relation.addSource(new TableColumnRelationshipElement(columnModel)); 22522 } 22523 } 22524 continue; 22525 } 22526 } 22527 } 22528 22529 if (columnName.getColumnNameOnly().startsWith("@") 22530 && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) { 22531 continue; 22532 } 22533 22534 if (columnName.getColumnNameOnly().startsWith(":") 22535 && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) { 22536 Table variable = modelManager 22537 .getTableByName(DlineageUtil.getTableFullName(columnName.getColumnNameOnly().replace(":", ""))); 22538 if (variable != null) { 22539 for (int j = 0; j < variable.getColumns().size(); j++) { 22540 if (getColumnName(columnName).replace(":", "") 22541 .equals(getColumnName(variable.getColumns().get(j).getColumnObject()))) { 22542 TableColumn columnModel = variable.getColumns().get(j); 22543 relation.addSource(new TableColumnRelationshipElement(columnModel)); 22544 } 22545 } 22546 } 22547 continue; 22548 } 22549 22550 boolean linkedFirstTable = false; 22551 22552 TCustomSqlStatement stmt = stmtStack.peek(); 22553 TTableList tableList = stmt.tables; 22554 if ((tableList == null || tableList.size() == 0) && (hiveFromTables != null && hiveFromTables.size() > 0)) { 22555 tableList = hiveFromTables; 22556 } 22557 22558 List<TTable> tables = new ArrayList<TTable>(); 22559 { 22560 TTable table = columnName.getSourceTable(); 22561 22562 // 针对CursorVariable特殊处理 22563 if (columnName.getTableToken() != null) { 22564 22565 Table tableModel = null; 22566 if (table != null && modelManager.getModel(table) instanceof Table) { 22567 tableModel = (Table) modelManager.getModel(table); 22568 } 22569 22570 if (tableModel == null) { 22571 tableModel = modelManager 22572 .getTableByName(DlineageUtil.getTableFullName(columnName.getTableToken().toString())); 22573 } 22574 22575 if (tableModel == null) { 22576 TCustomSqlStatement currentStmt = ModelBindingManager.getGlobalStmtStack().peek(); 22577 String procedureName = DlineageUtil.getProcedureParentName(currentStmt); 22578 String variableString = columnName.getTableToken().toString(); 22579 if (variableString.startsWith(":")) { 22580 variableString = variableString.substring(variableString.indexOf(":") + 1); 22581 } 22582 if (!SQLUtil.isEmpty(procedureName)) { 22583 variableString = procedureName + "." + SQLUtil.getIdentifierNormalTableName(variableString); 22584 } 22585 22586 if (modelManager 22587 .getTableByName(DlineageUtil.getTableFullName(variableString)) instanceof Variable) { 22588 tableModel = modelManager.getTableByName(DlineageUtil.getTableFullName(variableString)); 22589 } 22590 } 22591 22592 if (tableModel != null) { 22593 22594 if (table == null) { 22595 table = tableModel.getTableObject(); 22596 } 22597 22598 if (tableModel.isVariable()) { 22599 if (!isStar && "*".equals(getColumnName(columnName))) { 22600 TObjectName[] columns = modelManager.getTableColumns(table); 22601 for (int j = 0; j < columns.length; j++) { 22602 TObjectName objectName = columns[j]; 22603 if (objectName == null || "*".equals(getColumnName(objectName))) { 22604 continue; 22605 } 22606 TableColumn columnModel = modelFactory.createTableColumn(tableModel, objectName, 22607 false); 22608 relation.addSource(new TableColumnRelationshipElement(columnModel)); 22609 } 22610 } else { 22611 if ("*".equals(getColumnName(columnName)) && !tableModel.getColumns().isEmpty()) { 22612 22613 for (int j = 0; j < tableModel.getColumns().size(); j++) { 22614 TableColumn columnModel = tableModel.getColumns().get(j); 22615 if (exceptColumnList != null) { 22616 boolean flag = false; 22617 for (TObjectName objectName : exceptColumnList) { 22618 if (getColumnName(objectName) 22619 .equals(getColumnName(columnModel.getColumnObject()))) { 22620 flag = true; 22621 break; 22622 } 22623 } 22624 if (flag) { 22625 continue; 22626 } 22627 } 22628 relation.addSource(new TableColumnRelationshipElement(columnModel)); 22629 } 22630 22631 if (isStar && showStar) { 22632 TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName, 22633 false); 22634 if (columnModel == null) { 22635 if (tableModel.isCreateTable()) { 22636 for (TableColumn tableColumn : tableModel.getColumns()) { 22637 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 22638 relation.setShowStarRelation(true); 22639 } 22640 } 22641 } else { 22642 relation.addSource(new TableColumnRelationshipElement(columnModel)); 22643 relation.setShowStarRelation(true); 22644 } 22645 } 22646 } else { 22647 TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName, 22648 false); 22649 22650 if(columnModel == null && containStarColumn(tableModel.getColumns())){ 22651 columnModel = getStarColumn(tableModel.getColumns()); 22652 if (columnModel != null && tableModel.getSubType() == SubType.record_type) { 22653 if(!"*".equals(getColumnName(columnName))){ 22654 columnModel.bindStarLinkColumn(columnName); 22655 } 22656 } 22657 } 22658 22659 if (columnModel == null) { 22660 continue; 22661 } 22662 if (columnModel.hasStarLinkColumn()) { 22663 relation.addSource(new TableColumnRelationshipElement(columnModel, 22664 columnModel.getStarLinkColumnNames() 22665 .indexOf(DlineageUtil.getColumnName(columnName)))); 22666 } else { 22667 if (isOut) { 22668 relation.setTarget(new TableColumnRelationshipElement(columnModel)); 22669 } else { 22670 relation.addSource(new TableColumnRelationshipElement(columnModel)); 22671 } 22672 } 22673 if (columnName.getSourceTable() != null 22674 && columnName.getSourceTable().getTableType() == ETableSource.function) { 22675 analyzeTableColumn(columnModel, columnName.getSourceTable().getFuncCall(), 22676 effectType); 22677 } 22678 } 22679 } 22680 continue; 22681 } 22682 } 22683 } 22684 22685 if (table == null) { 22686 table = modelManager.getTable(stmt, columnName); 22687 } 22688 22689 if (table == null) { 22690 if (columnName.getTableToken() != null || !"*".equals(getColumnName(columnName))) { 22691 table = columnName.getSourceTable(); 22692 } 22693 22694 if (table == null && !SQLUtil.isEmpty(columnName.getTableString())) { 22695 table = modelManager.getTableFromColumn(columnName); 22696 } 22697 } 22698 22699 if (table == null) { 22700 if (tableList != null) { 22701 for (int j = 0; j < tableList.size(); j++) { 22702 if (table != null) 22703 break; 22704 22705 TTable tTable = tableList.getTable(j); 22706 if (tTable.getTableType().name().startsWith("open")) { 22707 continue; 22708 } 22709 22710 if (getTableLinkedColumns(tTable) != null && getTableLinkedColumns(tTable).size() > 0) { 22711 for (int z = 0; z < getTableLinkedColumns(tTable).size(); z++) { 22712 TObjectName refer = getTableLinkedColumns(tTable).getObjectName(z); 22713 if ("*".equals(getColumnName(refer))) 22714 continue; 22715 // For BigQuery struct field access, match base column name from FieldPath 22716 String structFullName = getStructFieldFullName(columnName); 22717 if (structFullName != null) { 22718 String baseName = getStructFieldBaseName(columnName); 22719 if (baseName != null && DlineageUtil.getIdentifierNormalColumnName(getColumnName(refer)) 22720 .equals(DlineageUtil.getIdentifierNormalColumnName(baseName))) { 22721 table = tTable; 22722 break; 22723 } 22724 } 22725 if (getColumnName(refer).equals(getColumnName(columnName))) { 22726 table = tTable; 22727 break; 22728 } 22729 } 22730 } 22731 22732 if (tTable.getLinkTable() != null) { 22733 tTable = tTable.getLinkTable(); 22734 for (int z = 0; z < getTableLinkedColumns(tTable).size(); z++) { 22735 TObjectName refer = getTableLinkedColumns(tTable).getObjectName(z); 22736 if ("*".equals(getColumnName(refer))) 22737 continue; 22738 if (getColumnName(refer).equals(getColumnName(columnName))) { 22739 table = tTable; 22740 break; 22741 } 22742 } 22743 } 22744 22745 if (table != null) 22746 break; 22747 22748 if (columnName.getTableToken() != null && (columnName.getTableToken().getAstext() 22749 .equalsIgnoreCase(tTable.getName()) 22750 || columnName.getTableToken().getAstext().equalsIgnoreCase(tTable.getAliasName()))) { 22751 table = tTable; 22752 break; 22753 } 22754 } 22755 } 22756 22757 if (table == null) { 22758 for (int j = 0; j < tableList.size(); j++) { 22759 if (table != null) 22760 break; 22761 22762 TTable tTable = tableList.getTable(j); 22763 Object model = ModelBindingManager.get().getModel(tTable); 22764 if (model instanceof Table) { 22765 Table tableModel = (Table) model; 22766 for (int z = 0; tableModel.getColumns() != null 22767 && z < tableModel.getColumns().size(); z++) { 22768 TableColumn refer = tableModel.getColumns().get(z); 22769 if (getColumnName(refer.getName()).equals(getColumnName(columnName))) { 22770 table = tTable; 22771 break; 22772 } 22773 if (refer.hasStarLinkColumn()) { 22774 for (TObjectName linkColumn : refer.getStarLinkColumnList()) { 22775 if (getColumnName(linkColumn).equals(getColumnName(columnName))) { 22776 table = tTable; 22777 break; 22778 } 22779 } 22780 } 22781 } 22782 } else if (model instanceof QueryTable) { 22783 QueryTable tableModel = (QueryTable) model; 22784 for (int z = 0; tableModel.getColumns() != null 22785 && z < tableModel.getColumns().size(); z++) { 22786 ResultColumn refer = tableModel.getColumns().get(z); 22787 // Try FieldPath-based matching first 22788 String structFullName = getStructFieldFullName(columnName); 22789 if (structFullName != null) { 22790 String baseName = getStructFieldBaseName(columnName); 22791 if (baseName != null && DlineageUtil.getIdentifierNormalColumnName(refer.getName()) 22792 .equals(DlineageUtil.getIdentifierNormalColumnName(baseName))) { 22793 table = tTable; 22794 break; 22795 } 22796 } 22797 List<String> splits = SQLUtil.parseNames(columnName.toString()); 22798 if (splits.size() > 1 && EDbVendor.dbvbigquery == getOption().getVendor()) { 22799 if (DlineageUtil.getIdentifierNormalColumnName(refer.getName()) 22800 .equals(DlineageUtil 22801 .getIdentifierNormalColumnName(getColumnName(splits.get(0))))) { 22802 table = tTable; 22803 break; 22804 } 22805 } 22806 else if (DlineageUtil.getIdentifierNormalColumnName(refer.getName()).equals( 22807 DlineageUtil.getIdentifierNormalColumnName(getColumnName(columnName)))) { 22808 table = tTable; 22809 break; 22810 } 22811 if (refer.hasStarLinkColumn()) { 22812 for (TObjectName linkColumn : refer.getStarLinkColumnList()) { 22813 if (getColumnName(linkColumn).equals(getColumnName(columnName))) { 22814 table = tTable; 22815 break; 22816 } 22817 } 22818 } 22819 } 22820 } 22821 } 22822 } 22823 } 22824 22825 if (columnName.getTableToken() == null && "*".equals(getColumnName(columnName))) { 22826 if (!hasJoin(stmt)) { 22827 tables.add(table); 22828 } else { 22829 for (int j = 0; j < tableList.size(); j++) { 22830 tables.add(tableList.getTable(j)); 22831 } 22832 } 22833 } else if (table != null) { 22834 tables.add(table); 22835 } 22836 22837 // 此处特殊处理,多表关联无法找到 column 所属的 Table, tTable.getLinkedColumns 22838 // 也找不到,退而求其次采用第一个表 22839 22840 if (stmt.getParentStmt() != null && isApplyJoin(stmt.getParentStmt()) 22841 && (tableList != null && tableList.size() > 0)) { 22842 stmt = stmt.getParentStmt(); 22843 TTable applyTable = tableList.getTable(0); 22844 if (modelManager.getModel(table) == null) { 22845 modelFactory.createTable(applyTable); 22846 } 22847 } 22848 22849 if (columnName.toString().indexOf(".")==-1 && isConstant(columnName)) { 22850 boolean isConstant = true; 22851 if (columnName.getSourceTable() != null) { 22852 Table tableModel = modelManager.getTableByName( 22853 DlineageUtil.getTableFullName(columnName.getSourceTable().getTableName().toString())); 22854 if (tableModel != null && tableModel.getColumns() != null) { 22855 for (int j = 0; j < tableModel.getColumns().size(); j++) { 22856 if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName), 22857 getColumnName(tableModel.getColumns().get(j).getName()))) { 22858 isConstant = false; 22859 break; 22860 } 22861 } 22862 } 22863 } 22864 22865 if (isConstant) { 22866 if (option.isShowConstantTable()) { 22867 Table constantTable = modelFactory.createConstantsTable(stmtStack.peek()); 22868 TableColumn tableColumn = modelFactory.createTableColumn(constantTable, columnName, false); 22869 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 22870 } 22871 continue; 22872 } 22873 } 22874 22875 if (tableList != null && tableList.size() != 0 && tables.size() == 0 22876 && !(isBuiltInFunctionName(columnName) && isFromFunction(columnName))) { 22877 if (modelManager.getModel(stmt) instanceof ResultSet) { 22878 ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt); 22879 boolean find = false; 22880 for (ResultColumn resultColumn : resultSetModel.getColumns()) { 22881 if(resultColumn.equals(modelObject)) { 22882 continue; 22883 } 22884 if (!TSQLEnv.isAliasReferenceForbidden.get(option.getVendor())) { 22885 if (getColumnName(columnName).equals(getColumnName(resultColumn.getName()))) { 22886 if (resultColumn.getColumnObject() != null) { 22887 int startToken = resultColumn.getColumnObject().getStartToken().posinlist; 22888 int endToken = resultColumn.getColumnObject().getEndToken().posinlist; 22889 if (columnName.getStartToken().posinlist >= startToken 22890 && columnName.getEndToken().posinlist <= endToken) { 22891 continue; 22892 } 22893 } 22894 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 22895 find = true; 22896 break; 22897 } 22898 } 22899 } 22900 if (find) { 22901 continue; 22902 } 22903 } 22904 22905 // Structured-dataflow outer field resolution: an unresolved 22906 // reference like nodes1.key (or t.nodes1.key) may be a 22907 // struct-field projection produced by a structured generator 22908 // (e.g. Spark explode(from_json(...))) in a visible subquery. 22909 // Link directly to the matching FunctionResultColumn so the 22910 // exact source path (nodes[*].key) flows through. 22911 if (tryAppendStructuredFieldRelation(relation, columnName, tableList)) { 22912 continue; 22913 } 22914 22915 TObjectName pseudoTableName = new TObjectName(); 22916 // Use qualified prefix from column name if available (e.g., sch.pk_constv2 from sch.pk_constv2.c_cdsl) 22917 // Otherwise fall back to default pseudo table name 22918 String qualifiedPrefix = getQualifiedPrefixFromColumn(columnName); 22919 pseudoTableName.setString(qualifiedPrefix != null ? qualifiedPrefix : "pseudo_table_include_orphan_column"); 22920 Table pseudoTable = modelFactory.createTableByName(pseudoTableName); 22921 pseudoTable.setPseudo(true); 22922 TableColumn pseudoTableColumn = modelFactory.createTableColumn(pseudoTable, columnName, true); 22923 22924 // If not linking to first table and column has qualified prefix (3-part name like sch.pkg.col), 22925 // add the pseudo table column as source 22926 if (!isLinkOrphanColumnToFirstTable() && pseudoTableColumn != null && qualifiedPrefix != null) { 22927 if (isOut) { 22928 relation.setTarget(new TableColumnRelationshipElement(pseudoTableColumn)); 22929 } else { 22930 relation.addSource(new TableColumnRelationshipElement(pseudoTableColumn)); 22931 } 22932 } 22933 22934 if (isLinkOrphanColumnToFirstTable()) { 22935 TTable orphanTable = tableList.getTable(0); 22936 tables.add(orphanTable); 22937 Object tableModel = modelManager.getModel(orphanTable); 22938 if (tableModel == null) { 22939 if(orphanTable.getSubquery()!=null) { 22940 QueryTable queryTable = modelFactory.createQueryTable(orphanTable); 22941 TSelectSqlStatement subquery = orphanTable.getSubquery(); 22942 analyzeSelectStmt(subquery); 22943 } 22944 else { 22945 tableModel = modelFactory.createTable(orphanTable); 22946 } 22947 } 22948 if (tableModel instanceof Table) { 22949 TableColumn orphanColum = modelFactory.createTableColumn((Table) tableModel, columnName, false); 22950 if(orphanColum!=null) { 22951 ErrorInfo errorInfo = new ErrorInfo(); 22952 errorInfo.setErrorType(ErrorInfo.LINK_ORPHAN_COLUMN); 22953 errorInfo.setErrorMessage("Link orphan column [" + columnName.toString() 22954 + "] to the first table [" + orphanTable.getFullNameWithAliasString() + "]"); 22955 errorInfo.setStartPosition(new Pair3<Long, Long, String>(columnName.getStartToken().lineNo, 22956 columnName.getStartToken().columnNo, ModelBindingManager.getGlobalHash())); 22957 errorInfo.setEndPosition(new Pair3<Long, Long, String>(columnName.getEndToken().lineNo, 22958 columnName.getEndToken().columnNo + columnName.getEndToken().getAstext().length(), 22959 ModelBindingManager.getGlobalHash())); 22960 errorInfo.fillInfo(this); 22961 errorInfos.add(errorInfo); 22962 } 22963 if (orphanTable.getSubquery() != null) { 22964 TSelectSqlStatement subquery = orphanTable.getSubquery(); 22965 if (subquery.getResultColumnList().toString().endsWith("*") && subquery.getTables().size() == 1) { 22966 TTable subqueryTable = subquery.getTables().getTable(0); 22967 Object sourceTable = modelManager.getModel(subqueryTable); 22968 if(sourceTable instanceof Table) { 22969 modelFactory.createTableColumn((Table) sourceTable, columnName, false); 22970 } 22971 else if(sourceTable instanceof ResultSet) { 22972 modelFactory.createResultColumn((ResultSet) sourceTable, columnName, false); 22973 } 22974 } 22975 } 22976 else if (orphanTable.getCTE()!=null && orphanTable.getCTE().getSubquery() != null) { 22977 TSelectSqlStatement subquery = orphanTable.getCTE().getSubquery(); 22978 if (subquery.getResultColumnList().toString().endsWith("*") && subquery.getTables().size() == 1) { 22979 TTable subqueryTable = subquery.getTables().getTable(0); 22980 Object sourceTable = modelManager.getModel(subqueryTable); 22981 if(sourceTable instanceof Table) { 22982 modelFactory.createTableColumn((Table) sourceTable, columnName, false); 22983 } 22984 else if(sourceTable instanceof ResultSet) { 22985 modelFactory.createResultColumn((ResultSet) sourceTable, columnName, false); 22986 } 22987 } 22988 } 22989 } 22990 22991 linkedFirstTable = true; 22992 } 22993 } 22994 } 22995 22996 for (int k = 0; k < tables.size(); k++) { 22997 TTable table = tables.get(k); 22998 if (table != null) { 22999 Object object = modelManager.getModel(table); 23000 if(object instanceof PivotedTable) { 23001 TPivotClause clause = (TPivotClause)((PivotedTable)object).getGspObject(); 23002 if(clause.getAliasClause()!=null) { 23003 object = modelManager.getModel(clause.getAliasClause()); 23004 } 23005 } 23006 if (object == null && table.getTableType() == ETableSource.objectname) { 23007 if (table.getCTE() != null) { 23008 QueryTable queryTable = modelFactory.createQueryTable(table); 23009 TSelectSqlStatement subquery = table.getCTE().getSubquery(); 23010 analyzeSelectStmt(subquery); 23011 ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery); 23012 23013 if (resultSetModel != null && resultSetModel != queryTable 23014 && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 23015 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 23016 impactRelation.setEffectType(EffectType.select); 23017 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 23018 resultSetModel.getRelationRows())); 23019 impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 23020 queryTable.getRelationRows())); 23021 } 23022 23023 if (resultSetModel != null && resultSetModel != queryTable) { 23024 for (int j = 0; j < resultSetModel.getColumns().size(); j++) { 23025 ResultColumn sourceColumn = resultSetModel.getColumns().get(j); 23026 ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable, 23027 sourceColumn); 23028 23029 DataFlowRelationship queryRalation = modelFactory.createDataFlowRelation(); 23030 queryRalation.setEffectType(EffectType.select); 23031 queryRalation.setTarget(new ResultColumnRelationshipElement(targetColumn)); 23032 queryRalation.addSource(new ResultColumnRelationshipElement(sourceColumn)); 23033 } 23034 } 23035 23036 object = queryTable; 23037 23038 } else { 23039 object = modelFactory.createTable(table); 23040 } 23041 } 23042 if (object instanceof Function) { 23043 relation.addSource(new ResultColumnRelationshipElement(((Function)object).getColumns().get(0))); 23044 continue; 23045 } else if (object instanceof ResultSet && !(object instanceof QueryTable)) { 23046 //Object tableModel = modelManager.getModel(columnName.getSourceTable()); 23047 appendResultColumnRelationSource(modelObject, relation, columnIndex, columnName, 23048 (ResultSet)object); 23049 if(table.getTableType() == ETableSource.function && !relation.getSources().isEmpty()) { 23050 relation.getSources().stream().reduce((first, second) -> second).get().addTransform(Transform.FUNCTION, table); 23051 } 23052 continue; 23053 } 23054 else if (object instanceof Table) { 23055 Table tableModel = (Table) modelManager.getModel(table); 23056 if (tableModel != null) { 23057 if (!isStar && "*".equals(getColumnName(columnName))) { 23058 TObjectName[] columns = modelManager.getTableColumns(table); 23059 for (int j = 0; j < columns.length; j++) { 23060 TObjectName objectName = columns[j]; 23061 if (objectName == null || ("*".equals(getColumnName(objectName)) && tableModel.isDetermined())) { 23062 continue; 23063 } 23064 TableColumn columnModel = modelFactory.createTableColumn(tableModel, objectName, 23065 false); 23066 if(columnModel == null) { 23067 continue; 23068 } 23069 relation.addSource(new TableColumnRelationshipElement(columnModel)); 23070 } 23071 } else { 23072 if ("*".equals(getColumnName(columnName)) && !tableModel.getColumns().isEmpty()) { 23073 Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>(); 23074 Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>(); 23075 if(modelObject instanceof ResultColumn && ((ResultColumn)modelObject).getColumnObject() instanceof TResultColumn) { 23076 TResultColumn resultColumn = (TResultColumn )((ResultColumn)modelObject).getColumnObject(); 23077 if(resultColumn.getReplaceExprAsIdentifiers()!=null && resultColumn.getReplaceExprAsIdentifiers().size()>0) { 23078 for(TReplaceExprAsIdentifier replace: resultColumn.getReplaceExprAsIdentifiers()) { 23079 replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(resultColumn.getExpr().getExceptReplaceClause().toString(), replace.getExpr())); 23080 replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier()); 23081 } 23082 ResultSet resultSet = ((ResultColumn)modelObject).getResultSet(); 23083 if(tableModel.isDetermined()) { 23084 resultSet.getColumns().clear(); 23085 } 23086 } 23087 } 23088 23089 for (int j = 0; j < tableModel.getColumns().size(); j++) { 23090 TableColumn columnModel = tableModel.getColumns().get(j); 23091 if (exceptColumnList != null) { 23092 boolean flag = false; 23093 for (TObjectName objectName : exceptColumnList) { 23094 if (getColumnName(objectName) 23095 .equals(getColumnName(columnModel.getColumnObject()))) { 23096 flag = true; 23097 break; 23098 } 23099 } 23100 if (flag) { 23101 continue; 23102 } 23103 } 23104 23105 if (replaceAsIdentifierMap.containsKey(tableModel.getColumns().get(j).getName())) { 23106 Pair<String, TExpression> expr = replaceAsIdentifierMap.get(tableModel.getColumns().get(j).getName()); 23107 ResultSet resultSet = ((ResultColumn)modelObject).getResultSet(); 23108 ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, replaceColumnMap.get(tableModel.getColumns().get(j).getName())); 23109 Transform transform = new Transform(); 23110 transform.setType(Transform.EXPRESSION); 23111 TObjectName expression = new TObjectName(); 23112 expression.setString(expr.first); 23113 transform.setCode(expression); 23114 resultColumn.setTransform(transform); 23115 analyzeResultColumnExpressionRelation(resultColumn, expr.second); 23116 } else { 23117 if(!replaceAsIdentifierMap.isEmpty()) { 23118 ResultSet resultSet = ((ResultColumn) modelObject).getResultSet(); 23119 ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, 23120 columnModel.getColumnObject()); 23121 DataFlowRelationship relation1 = modelFactory.createDataFlowRelation(); 23122 relation1.setEffectType(effectType); 23123 relation1.setProcess(process); 23124 relation1.setTarget(new ResultColumnRelationshipElement(resultColumn)); 23125 relation1.addSource(new TableColumnRelationshipElement(columnModel)); 23126 } 23127 else { 23128 relation.addSource( 23129 new TableColumnRelationshipElement(columnModel)); 23130 } 23131 } 23132 } 23133 23134 if (isStar && showStar) { 23135 TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName, 23136 false); 23137 if (columnModel == null) { 23138 if(tableModel.isCreateTable()) { 23139 for (TableColumn tableColumn : tableModel.getColumns()) { 23140 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 23141 relation.setShowStarRelation(true); 23142 } 23143 } 23144 } else { 23145 relation.addSource(new TableColumnRelationshipElement(columnModel)); 23146 relation.setShowStarRelation(true); 23147 } 23148 } 23149 } else { 23150 TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName, 23151 false); 23152 if(columnModel == null) { 23153 if(tableModel.isCreateTable()) { 23154 boolean flag = false; 23155 // Try FieldPath-based matching first for BigQuery/Redshift struct fields 23156 String structFullName = getStructFieldFullName(columnName); 23157 if (structFullName != null && !flag) { 23158 for (TableColumn tableColumn : tableModel.getColumns()) { 23159 if (tableColumn.isStruct() 23160 && DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()) 23161 .equals(DlineageUtil.getIdentifierNormalColumnName(structFullName))) { 23162 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 23163 flag = true; 23164 if (modelObject instanceof ResultColumn) { 23165 ((ResultColumn) modelObject).setStruct(true); 23166 } else if (modelObject instanceof TableColumn) { 23167 ((TableColumn) modelObject).setStruct(true); 23168 } 23169 break; 23170 } 23171 } 23172 } 23173 if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvbigquery || ModelBindingManager.getGlobalVendor() == EDbVendor.dbvredshift) { 23174 for (TableColumn tableColumn : tableModel.getColumns()) { 23175 if(tableColumn.isStruct()) { 23176 List<String> names = SQLUtil.parseNames(tableColumn.getName()); 23177 if (modelObject instanceof TableColumn) { 23178 TableColumn targetColumn = (TableColumn) modelObject; 23179 if (targetColumn.isStruct()) { 23180 List<String> targetNames = SQLUtil 23181 .parseNames(targetColumn.getName()); 23182 if (!getColumnName(targetNames.get(0)) 23183 .equals(getColumnName(names.get(0)))) { 23184 continue; 23185 } 23186 } 23187 } 23188 else if (modelObject instanceof ResultColumn) { 23189 ResultColumn targetColumn = (ResultColumn) modelObject; 23190 if (targetColumn.isStruct()) { 23191 List<String> targetNames = SQLUtil 23192 .parseNames(targetColumn.getName()); 23193 if (!getColumnName(targetNames.get(0)) 23194 .equals(getColumnName(names.get(0)))) { 23195 continue; 23196 } 23197 } 23198 } 23199 for(String name: names) { 23200 if (getColumnName(name) 23201 .equals(getColumnName(modelObject.toString()))) { 23202 relation.addSource( 23203 new TableColumnRelationshipElement(tableColumn)); 23204 flag = true; 23205 if (modelObject instanceof ResultColumn) { 23206 ((ResultColumn)modelObject).setStruct(true); 23207 } 23208 else if (modelObject instanceof TableColumn) { 23209 ((TableColumn)modelObject).setStruct(true); 23210 } 23211 break; 23212 } 23213 } 23214 23215 if (!flag && tableModel.getColumns().size() == 1 && tableModel 23216 .getColumns().get(0).getSourceColumn() != null) { 23217 TableColumn sourceColumn = tableModel 23218 .getColumns().get(0).getSourceColumn(); 23219 Table sourceTable = sourceColumn.getTable(); 23220 TObjectName sourceColumnName = new TObjectName(); 23221 sourceColumnName.setString(sourceColumn.getName() + "." 23222 + columnName.getColumnNameOnly()); 23223 TableColumn sourceTableColumn = modelFactory.createTableColumn(sourceTable, sourceColumnName, true); 23224 relation.addSource( 23225 new TableColumnRelationshipElement(sourceTableColumn)); 23226 flag = true; 23227 break; 23228 } 23229 } 23230 else if (getColumnName(tableColumn.getName()) 23231 .equals(getColumnName(modelObject.toString()))) { 23232 relation.addSource( 23233 new TableColumnRelationshipElement(tableColumn)); 23234 flag = true; 23235 break; 23236 } 23237 } 23238 if (modelObject instanceof TableColumn) { 23239 TableColumn column = (TableColumn) modelObject; 23240 for (TableColumn tableColumn : tableModel.getColumns()) { 23241 if (tableColumn.getColumnIndex() == null) { 23242 continue; 23243 } 23244 if (tableColumn.getName().toLowerCase() 23245 .indexOf(column.getName().toLowerCase()) == -1 23246 && tableColumn.getName().toLowerCase() 23247 .indexOf(column.getColumnObject().toString() 23248 .toLowerCase()) == -1) { 23249 continue; 23250 } 23251 flag = true; 23252 relation.addSource( 23253 new TableColumnRelationshipElement(tableColumn)); 23254 relation.setShowStarRelation(true); 23255 } 23256 if (flag) 23257 break; 23258 23259 } else if (modelObject instanceof ResultColumn) { 23260 ResultColumn column = (ResultColumn) modelObject; 23261 for (TableColumn tableColumn : tableModel.getColumns()) { 23262 if (tableColumn.getColumnIndex() == null) { 23263 continue; 23264 } 23265 if (tableColumn.getName().toLowerCase() 23266 .indexOf(column.getName().toLowerCase()) == -1 23267 && tableColumn.getName().toLowerCase() 23268 .indexOf(column.getColumnObject().toString() 23269 .toLowerCase()) == -1) { 23270 continue; 23271 } 23272 flag = true; 23273 relation.addSource( 23274 new TableColumnRelationshipElement(tableColumn)); 23275 relation.setShowStarRelation(true); 23276 } 23277 if (flag) 23278 break; 23279 23280 } 23281 } 23282 if (!flag 23283 && (isStar 23284 || getColumnName(columnName).equals(getColumnName(tableModel.getName())) 23285 || getColumnName(columnName).equals(getColumnName(tableModel.getAlias())))) { 23286 for (TableColumn tableColumn : tableModel.getColumns()) { 23287 relation.addSource(new TableColumnRelationshipElement(tableColumn)); 23288 relation.setShowStarRelation(true); 23289 } 23290 } 23291 } 23292 } 23293 else { 23294 if (linkedFirstTable || columnModel.getCandidateParents() != null) { 23295 if (columnName.getCandidateTables() != null 23296 && columnName.getCandidateTables().size() > 1) { 23297 List<Object> candidateParents = new ArrayList<Object>(); 23298 for(TTable tableItem: columnName.getCandidateTables()) { 23299 Object model = modelManager.getModel(tableItem); 23300 if(model!=null) { 23301 candidateParents.add(model); 23302 } 23303 } 23304 if (candidateParents.size() > 1) { 23305 columnModel.setCandidateParents(candidateParents); 23306 } 23307 } 23308 } 23309 relation.addSource(new TableColumnRelationshipElement(columnModel)); 23310 relation.setShowStarRelation(true); 23311 if(modelObject instanceof TableColumn) { 23312 TableColumn targetTableColumn = (TableColumn)modelObject; 23313 if(targetTableColumn.getTable().getSubType() == SubType.unnest && targetTableColumn.getTable().getColumns().size() == 1) { 23314 targetTableColumn.setSourceColumn(columnModel); 23315 targetTableColumn.setStruct(true); 23316 } 23317 } 23318 if (columnName.getSourceTable() != null 23319 && columnName.getSourceTable().getTableType() == ETableSource.function) { 23320 analyzeTableColumn(columnModel, columnName.getSourceTable().getFuncCall(), 23321 effectType); 23322 } 23323 } 23324 } 23325 } 23326 } 23327 } else if (modelManager.getModel(table) instanceof QueryTable) { 23328 QueryTable queryTable = (QueryTable) modelManager.getModel(table); 23329 23330 TObjectNameList cteColumns = null; 23331 TSelectSqlStatement subquery = null; 23332 if (queryTable.getTableObject().getCTE() != null) { 23333 subquery = queryTable.getTableObject().getCTE().getSubquery(); 23334 cteColumns = queryTable.getTableObject().getCTE().getColumnList(); 23335 } else if (queryTable.getTableObject().getAliasClause() != null 23336 && queryTable.getTableObject().getAliasClause().getColumns() != null) { 23337 23338 } else if (queryTable.getTableObject().getTableExpr() != null 23339 && queryTable.getTableObject().getTableExpr().getSubQuery() != null) { 23340 subquery = queryTable.getTableObject().getTableExpr().getSubQuery(); 23341 } else { 23342 subquery = queryTable.getTableObject().getSubquery(); 23343 } 23344 23345 if (cteColumns != null) { 23346 for (int j = 0; j < cteColumns.size(); j++) { 23347 modelFactory.createResultColumn(queryTable, cteColumns.getObjectName(j)); 23348 } 23349 } 23350 23351 if (subquery != null && subquery.isCombinedQuery()) { 23352 SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager 23353 .getModel(subquery); 23354 23355 if (selectSetResultSetModel != null 23356 && !selectSetResultSetModel.getRelationRows().getHoldRelations().isEmpty()) { 23357 ImpactRelationship impactRelation = modelFactory.createImpactRelation(); 23358 impactRelation.setEffectType(EffectType.select); 23359 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 23360 selectSetResultSetModel.getRelationRows())); 23361 impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 23362 queryTable.getRelationRows())); 23363 } 23364 23365 if (selectSetResultSetModel != null) { 23366 if (getColumnName(columnName).equals("*")) { 23367 Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>(); 23368 Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>(); 23369 if(modelObject instanceof ResultColumn && ((ResultColumn)modelObject).getColumnObject() instanceof TResultColumn) { 23370 TResultColumn resultColumn = (TResultColumn )((ResultColumn)modelObject).getColumnObject(); 23371 if(resultColumn.getReplaceExprAsIdentifiers()!=null && resultColumn.getReplaceExprAsIdentifiers().size()>0) { 23372 for(TReplaceExprAsIdentifier replace: resultColumn.getReplaceExprAsIdentifiers()) { 23373 replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(resultColumn.getExpr().getExceptReplaceClause().toString(), replace.getExpr())); 23374 replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier()); 23375 } 23376 ResultSet resultSet = ((ResultColumn)modelObject).getResultSet(); 23377 if(selectSetResultSetModel.isDetermined()) { 23378 resultSet.getColumns().clear(); 23379 } 23380 } 23381 } 23382 23383 23384 for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) { 23385 ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j); 23386 if (cteColumns != null) { 23387 if (j < cteColumns.size()) { 23388 ResultColumn targetColumn = queryTable.getColumns().get(j); 23389 23390 if (exceptColumnList != null) { 23391 boolean flag = false; 23392 for (TObjectName objectName : exceptColumnList) { 23393 if (getColumnName(objectName) 23394 .equals(getColumnName(targetColumn.getName()))) { 23395 flag = true; 23396 break; 23397 } 23398 } 23399 if (flag) { 23400 continue; 23401 } 23402 } 23403 23404 if (replaceAsIdentifierMap.containsKey(targetColumn.getName())) { 23405 Pair<String, TExpression> expr = replaceAsIdentifierMap.get(targetColumn.getName()); 23406 ResultSet resultSet = ((ResultColumn)modelObject).getResultSet(); 23407 ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, replaceColumnMap.get(targetColumn.getName())); 23408 Transform transform = new Transform(); 23409 transform.setType(Transform.EXPRESSION); 23410 TObjectName expression = new TObjectName(); 23411 expression.setString(expr.first); 23412 transform.setCode(expression); 23413 resultColumn.setTransform(transform); 23414 analyzeResultColumnExpressionRelation(resultColumn, expr.second); 23415 } else { 23416 if(!replaceAsIdentifierMap.isEmpty()) { 23417 ResultSet resultSet = ((ResultColumn) modelObject).getResultSet(); 23418 TObjectName resultColumnName = new TObjectName(); 23419 resultColumnName.setString(targetColumn.getName()); 23420 ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, 23421 resultColumnName); 23422 DataFlowRelationship relation1 = modelFactory.createDataFlowRelation(); 23423 relation1.setEffectType(effectType); 23424 relation1.setProcess(process); 23425 relation1.setTarget(new ResultColumnRelationshipElement(resultColumn)); 23426 relation1.addSource(new ResultColumnRelationshipElement(targetColumn)); 23427 } 23428 else { 23429 relation.addSource( 23430 new ResultColumnRelationshipElement(targetColumn)); 23431 } 23432 } 23433 23434 } 23435 } else { 23436 ResultColumn targetColumn = modelFactory 23437 .createSelectSetResultColumn(queryTable, sourceColumn); 23438 23439 DataFlowRelationship combinedQueryRelation = modelFactory 23440 .createDataFlowRelation(); 23441 combinedQueryRelation.setEffectType(effectType); 23442 combinedQueryRelation 23443 .setTarget(new ResultColumnRelationshipElement(targetColumn)); 23444 combinedQueryRelation 23445 .addSource(new ResultColumnRelationshipElement(sourceColumn)); 23446 23447 relation.addSource(new ResultColumnRelationshipElement(targetColumn)); 23448 } 23449 } 23450 break; 23451 } else { 23452 boolean flag = false; 23453 23454 for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) { 23455 ResultColumn sourceColumn = selectSetResultSetModel 23456 .getColumns().get(j); 23457 List<String> splits = SQLUtil.parseNames(columnName.toString()); 23458 if (splits.size() > 1 && EDbVendor.dbvbigquery == getOption().getVendor()) { 23459 if (getColumnName(sourceColumn.getName()) 23460 .equalsIgnoreCase(getColumnName(splits.get(0))) 23461 || getColumnName(sourceColumn.getName()) 23462 .equalsIgnoreCase(getColumnName(splits.get(1)))) { 23463 ResultColumn targetColumn = modelFactory 23464 .createSelectSetResultColumn(queryTable, sourceColumn); 23465 23466 DataFlowRelationship combinedQueryRelation = modelFactory 23467 .createDataFlowRelation(); 23468 combinedQueryRelation.setEffectType(effectType); 23469 combinedQueryRelation.setTarget( 23470 new ResultColumnRelationshipElement(targetColumn)); 23471 combinedQueryRelation.addSource( 23472 new ResultColumnRelationshipElement(sourceColumn)); 23473 23474 relation.addSource( 23475 new ResultColumnRelationshipElement(targetColumn)); 23476 flag = true; 23477 break; 23478 } 23479 } 23480 else if (getColumnName(sourceColumn.getName()) 23481 .equalsIgnoreCase(getColumnName(columnName))) { 23482 ResultColumn targetColumn = modelFactory 23483 .createSelectSetResultColumn(queryTable, sourceColumn); 23484 23485 DataFlowRelationship combinedQueryRelation = modelFactory 23486 .createDataFlowRelation(); 23487 combinedQueryRelation.setEffectType(effectType); 23488 combinedQueryRelation 23489 .setTarget(new ResultColumnRelationshipElement(targetColumn)); 23490 combinedQueryRelation 23491 .addSource(new ResultColumnRelationshipElement(sourceColumn)); 23492 23493 relation.addSource(new ResultColumnRelationshipElement(targetColumn)); 23494 flag = true; 23495 break; 23496 } 23497 else if (sourceColumn instanceof SelectSetResultColumn && ((SelectSetResultColumn)sourceColumn).getAliasSet().size() > 1) { 23498 for (String alias : ((SelectSetResultColumn)sourceColumn).getAliasSet()) { 23499 if (getColumnName(alias).equalsIgnoreCase(getColumnName(columnName))) { 23500 ResultColumn targetColumn = modelFactory 23501 .createSelectSetResultColumn(queryTable, sourceColumn); 23502 23503 DataFlowRelationship combinedQueryRelation = modelFactory 23504 .createDataFlowRelation(); 23505 combinedQueryRelation.setEffectType(effectType); 23506 combinedQueryRelation.setTarget( 23507 new ResultColumnRelationshipElement(targetColumn)); 23508 combinedQueryRelation.addSource( 23509 new ResultColumnRelationshipElement(sourceColumn)); 23510 23511 relation.addSource( 23512 new ResultColumnRelationshipElement(targetColumn)); 23513 flag = true; 23514 break; 23515 } 23516 } 23517 if (flag) { 23518 break; 23519 } 23520 } 23521 } 23522 23523 if (flag) { 23524 break; 23525 } else if (columnIndex != -1) { 23526 for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) { 23527 ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j); 23528 if (!sourceColumn.getStarLinkColumns().isEmpty()) { 23529 if (cteColumns != null) { 23530 if (j < cteColumns.size()) { 23531 ResultColumn targetColumn = queryTable.getColumns().get(j); 23532 relation.addSource( 23533 new ResultColumnRelationshipElement(targetColumn)); 23534 } 23535 } 23536 else { 23537 if(sourceColumn.hasStarLinkColumn()) { 23538 for (TObjectName linkColumn : sourceColumn.getStarLinkColumnList()) { 23539 if (getColumnName(linkColumn).equals(getColumnName(columnName))) { 23540 ResultColumn targetColumn = modelFactory 23541 .createSelectSetResultColumn(queryTable, sourceColumn); 23542 23543 DataFlowRelationship combinedQueryRelation = modelFactory 23544 .createDataFlowRelation(); 23545 combinedQueryRelation.setEffectType(effectType); 23546 combinedQueryRelation.setTarget( 23547 new ResultColumnRelationshipElement(targetColumn, linkColumn)); 23548 combinedQueryRelation.addSource( 23549 new ResultColumnRelationshipElement(sourceColumn)); 23550 23551 relation.addSource( 23552 new ResultColumnRelationshipElement(targetColumn, linkColumn)); 23553 flag = true; 23554 break; 23555 } 23556 } 23557 } 23558 23559 if(!flag) { 23560 ResultColumn targetColumn = modelFactory 23561 .createSelectSetResultColumn(queryTable, sourceColumn); 23562 23563 DataFlowRelationship combinedQueryRelation = modelFactory 23564 .createDataFlowRelation(); 23565 combinedQueryRelation.setEffectType(effectType); 23566 combinedQueryRelation.setTarget( 23567 new ResultColumnRelationshipElement(targetColumn)); 23568 combinedQueryRelation.addSource( 23569 new ResultColumnRelationshipElement(sourceColumn)); 23570 23571 relation.addSource( 23572 new ResultColumnRelationshipElement(targetColumn)); 23573 } 23574 } 23575 flag = true; 23576 break; 23577 } 23578 } 23579 } 23580 23581 if (flag) { 23582 break; 23583 } else if (columnIndex < selectSetResultSetModel.getColumns().size() 23584 && columnIndex != -1) { 23585 ResultColumn sourceColumn = selectSetResultSetModel.getColumns() 23586 .get(columnIndex); 23587 if (cteColumns != null) { 23588 boolean flag1 = false; 23589 for (ResultColumn targetColumn : queryTable.getColumns()) { 23590 if (getColumnName(targetColumn.getName()) 23591 .equalsIgnoreCase(getColumnName(columnName))) { 23592 relation.addSource( 23593 new ResultColumnRelationshipElement(targetColumn)); 23594 flag1 = true; 23595 break; 23596 } 23597 } 23598 if (!flag1 && columnIndex < cteColumns.size()){ 23599 ResultColumn targetColumn = queryTable.getColumns() 23600 .get(columnIndex); 23601 relation.addSource( 23602 new ResultColumnRelationshipElement(targetColumn)); 23603 } 23604 } else { 23605 ResultColumn targetColumn = modelFactory 23606 .createSelectSetResultColumn(queryTable, sourceColumn); 23607 23608 DataFlowRelationship combinedQueryRelation = modelFactory 23609 .createDataFlowRelation(); 23610 combinedQueryRelation.setEffectType(effectType); 23611 combinedQueryRelation 23612 .setTarget(new ResultColumnRelationshipElement(targetColumn)); 23613 combinedQueryRelation 23614 .addSource(new ResultColumnRelationshipElement(sourceColumn)); 23615 23616 relation.addSource(new ResultColumnRelationshipElement(targetColumn)); 23617 } 23618 flag = true; 23619 break; 23620 } 23621 23622 if (flag) { 23623 break; 23624 } 23625 } 23626 } else if (cteColumns != null) { 23627 if (getColumnName(columnName).equals("*")) { 23628 Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>(); 23629 Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>(); 23630 if(modelObject instanceof ResultColumn && ((ResultColumn)modelObject).getColumnObject() instanceof TResultColumn) { 23631 TResultColumn resultColumn = (TResultColumn )((ResultColumn)modelObject).getColumnObject(); 23632 if(resultColumn.getReplaceExprAsIdentifiers()!=null && resultColumn.getReplaceExprAsIdentifiers().size()>0) { 23633 for(TReplaceExprAsIdentifier replace: resultColumn.getReplaceExprAsIdentifiers()) { 23634 replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(resultColumn.getExpr().getExceptReplaceClause().toString(), replace.getExpr())); 23635 replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier()); 23636 } 23637 ResultSet resultSet = ((ResultColumn)modelObject).getResultSet(); 23638 23639 if (columnName.getSourceColumn() != null) { 23640 Object model = modelManager.getModel(columnName.getSourceColumn()); 23641 if (model instanceof ResultColumn && ((ResultColumn)model).getResultSet().isDetermined()) { 23642 resultSet.getColumns().clear(); 23643 } 23644 } else if (columnName.getSourceTable() != null) { 23645 Object tableModel = modelManager.getModel(columnName.getSourceTable()); 23646 if (tableModel instanceof Table && ((Table)tableModel).isDetermined()) { 23647 resultSet.getColumns().clear(); 23648 } 23649 } 23650 } 23651 } 23652 23653 for (int j = 0; j < cteColumns.size(); j++) { 23654 ResultColumn targetColumn = queryTable.getColumns().get(j); 23655 23656 if (exceptColumnList != null) { 23657 boolean flag = false; 23658 for (TObjectName objectName : exceptColumnList) { 23659 if (getColumnName(objectName) 23660 .equals(getColumnName(targetColumn.getName()))) { 23661 flag = true; 23662 break; 23663 } 23664 } 23665 if (flag) { 23666 continue; 23667 } 23668 } 23669 23670 if (replaceAsIdentifierMap.containsKey(targetColumn.getName())) { 23671 Pair<String, TExpression> expr = replaceAsIdentifierMap.get(targetColumn.getName()); 23672 ResultSet resultSet = ((ResultColumn)modelObject).getResultSet(); 23673 ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, replaceColumnMap.get(targetColumn.getName())); 23674 Transform transform = new Transform(); 23675 transform.setType(Transform.EXPRESSION); 23676 TObjectName expression = new TObjectName(); 23677 expression.setString(expr.first); 23678 transform.setCode(expression); 23679 resultColumn.setTransform(transform); 23680 analyzeResultColumnExpressionRelation(resultColumn, expr.second); 23681 } else { 23682 if(!replaceAsIdentifierMap.isEmpty()) { 23683 ResultSet resultSet = ((ResultColumn) modelObject).getResultSet(); 23684 TObjectName resultColumnName = new TObjectName(); 23685 resultColumnName.setString(targetColumn.getName()); 23686 ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, 23687 resultColumnName); 23688 DataFlowRelationship relation1 = modelFactory.createDataFlowRelation(); 23689 relation1.setEffectType(effectType); 23690 relation1.setProcess(process); 23691 relation1.setTarget(new ResultColumnRelationshipElement(resultColumn)); 23692 relation1.addSource(new ResultColumnRelationshipElement(targetColumn)); 23693 } 23694 else { 23695 relation.addSource( 23696 new ResultColumnRelationshipElement(targetColumn)); 23697 } 23698 } 23699 } 23700 break; 23701 } else { 23702 boolean flag = false; 23703 23704 for (int j = 0; j < cteColumns.size(); j++) { 23705 TObjectName sourceColumn = cteColumns.getObjectName(j); 23706 23707 if (getColumnName(sourceColumn).equalsIgnoreCase(getColumnName(columnName))) { 23708 ResultColumn targetColumn = queryTable.getColumns().get(j); 23709 23710 relation.addSource(new ResultColumnRelationshipElement(targetColumn)); 23711 flag = true; 23712 break; 23713 } 23714 } 23715 23716 if (flag) { 23717 break; 23718 } 23719 } 23720 } 23721 23722 if (columnName.getSourceColumn() != null) { 23723 Object model = modelManager.getModel(columnName.getSourceColumn()); 23724 if (model instanceof ResultColumn) { 23725 ResultColumn resultColumn = (ResultColumn) model; 23726 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 23727 } 23728 } else if (columnName.getSourceTable() != null) { 23729 Object tableModel = modelManager.getModel(columnName.getSourceTable()); 23730 if (tableModel instanceof Table) { 23731 Object model = modelManager 23732 .getModel(new Pair<Table, TObjectName>((Table) tableModel, columnName)); 23733 if (model instanceof TableColumn) { 23734 relation.addSource(new TableColumnRelationshipElement((TableColumn) model)); 23735 } 23736 } 23737 } 23738 } else { 23739 List<ResultColumn> columns = queryTable.getColumns(); 23740 if (getColumnName(columnName).equals("*")) { 23741 Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>(); 23742 Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>(); 23743 if(modelObject instanceof ResultColumn && ((ResultColumn)modelObject).getColumnObject() instanceof TResultColumn) { 23744 TResultColumn resultColumn = (TResultColumn )((ResultColumn)modelObject).getColumnObject(); 23745 if(resultColumn.getReplaceExprAsIdentifiers()!=null && resultColumn.getReplaceExprAsIdentifiers().size()>0) { 23746 for(TReplaceExprAsIdentifier replace: resultColumn.getReplaceExprAsIdentifiers()) { 23747 replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(resultColumn.getExpr().getExceptReplaceClause().toString(), replace.getExpr())); 23748 replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier()); 23749 } 23750 ResultSet resultSet = ((ResultColumn)modelObject).getResultSet(); 23751 if(queryTable.isDetermined()) { 23752 resultSet.getColumns().clear(); 23753 } 23754 } 23755 } 23756 23757 int index = 0; 23758 for (int j = 0; j < queryTable.getColumns().size(); j++) { 23759 ResultColumn targetColumn = queryTable.getColumns().get(j); 23760 if (exceptColumnList != null) { 23761 boolean flag = false; 23762 for (TObjectName objectName : exceptColumnList) { 23763 if (getColumnName(objectName) 23764 .equals(getColumnName(targetColumn.getName()))) { 23765 flag = true; 23766 break; 23767 } 23768 } 23769 if (flag) { 23770 continue; 23771 } 23772 } 23773 23774 if (replaceAsIdentifierMap.containsKey(targetColumn.getName())) { 23775 Pair<String, TExpression> expr = replaceAsIdentifierMap.get(targetColumn.getName()); 23776 ResultSet resultSet = ((ResultColumn)modelObject).getResultSet(); 23777 ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, replaceColumnMap.get(targetColumn.getName())); 23778 Transform transform = new Transform(); 23779 transform.setType(Transform.EXPRESSION); 23780 TObjectName expression = new TObjectName(); 23781 expression.setString(expr.first); 23782 transform.setCode(expression); 23783 resultColumn.setTransform(transform); 23784 analyzeResultColumnExpressionRelation(resultColumn, expr.second); 23785 } else { 23786 if(!replaceAsIdentifierMap.isEmpty()) { 23787 ResultSet resultSet = ((ResultColumn) modelObject).getResultSet(); 23788 TObjectName resultColumnName = new TObjectName(); 23789 resultColumnName.setString(targetColumn.getName()); 23790 ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, 23791 resultColumnName); 23792 DataFlowRelationship relation1 = modelFactory.createDataFlowRelation(); 23793 relation1.setEffectType(effectType); 23794 relation1.setProcess(process); 23795 relation1.setTarget(new ResultColumnRelationshipElement(resultColumn)); 23796 relation1.addSource(new ResultColumnRelationshipElement(targetColumn)); 23797 } 23798 else { 23799 relation.addSource( 23800 new ResultColumnRelationshipElement(targetColumn)); 23801 } 23802 } 23803 index++; 23804 } 23805 } else { 23806 if (table.getCTE() != null) { 23807 23808 if (modelObject instanceof TableColumn) { 23809 Table modelTable = ((TableColumn) modelObject).getTable(); 23810 if (modelTable.getSubType() == SubType.unnest) { 23811 boolean find = false; 23812 for (k = 0; k < columns.size(); k++) { 23813 ResultColumn column = columns.get(k); 23814 if (column.isStruct()) { 23815 List<String> names = SQLUtil.parseNames(column.getName()); 23816 for (String name : names) { 23817 if (getColumnName(name).equals(getColumnName(columnName))) { 23818 DataFlowRelationship unnestRelation = modelFactory.createDataFlowRelation(); 23819 unnestRelation.setEffectType(effectType); 23820 unnestRelation.setProcess(process); 23821 unnestRelation.addSource(new ResultColumnRelationshipElement( 23822 column, columnName)); 23823 TObjectName unnestTableColumnName = new TObjectName(); 23824 unnestTableColumnName.setString(names.get(names.size()-1)); 23825 TableColumn unnestTableColumn = modelFactory.createTableColumn(modelTable, unnestTableColumnName, true); 23826 unnestRelation.setTarget(new TableColumnRelationshipElement(unnestTableColumn)); 23827 find = true; 23828 } 23829 } 23830 List<String> names1 = SQLUtil.parseNames(column.getName()); 23831 if (names.size() == 1 && names1.size() >= 1) { 23832 for (String name : names1) { 23833 if (getColumnName(name) 23834 .equals(getColumnName(column.getName()))) { 23835 DataFlowRelationship unnestRelation = modelFactory.createDataFlowRelation(); 23836 unnestRelation.setEffectType(effectType); 23837 unnestRelation.setProcess(process); 23838 unnestRelation.addSource(new ResultColumnRelationshipElement( 23839 column, columnName)); 23840 TObjectName unnestTableColumnName = new TObjectName(); 23841 unnestTableColumnName.setString(names1.get(names.size()-1)); 23842 TableColumn unnestTableColumn = modelFactory.createTableColumn(modelTable, unnestTableColumnName, true); 23843 unnestRelation.setTarget(new TableColumnRelationshipElement(unnestTableColumn)); 23844 find = true; 23845 } 23846 } 23847 } 23848 } 23849 } 23850 if (find) { 23851 modelTable.getColumns().remove(modelObject); 23852 break; 23853 } 23854 } 23855 } 23856 23857 for (k = 0; k < columns.size(); k++) { 23858 ResultColumn column = columns.get(k); 23859 if ("*".equals(column.getName())) { 23860 if (!containsStarColumn(column, columnName)) { 23861 column.bindStarLinkColumn(columnName); 23862 } 23863 relation.addSource(new ResultColumnRelationshipElement(column, columnName)); 23864 } else if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName), 23865 DlineageUtil.getIdentifierNormalColumnName(column.getName()))) { 23866 if (!column.equals(modelObject)) { 23867 relation.addSource( 23868 new ResultColumnRelationshipElement(column, columnName)); 23869 } 23870 break; 23871 } else if(column.isStruct()) { 23872 List<String> names = SQLUtil.parseNames(column.getName()); 23873 for(String name: names) { 23874 if (getColumnName(name) 23875 .equals(getColumnName(columnName))) { 23876 relation.addSource( 23877 new ResultColumnRelationshipElement(column, columnName)); 23878 } 23879 } 23880 List<String> names1 = SQLUtil.parseNames(column.getName()); 23881 if (names.size() == 1 && names1.size() >= 1) { 23882 for(String name: names1) { 23883 if (getColumnName(name) 23884 .equals(getColumnName(column.getName()))) { 23885 relation.addSource( 23886 new ResultColumnRelationshipElement(column, columnName)); 23887 } 23888 } 23889 } 23890 } 23891 } 23892 } else if (table.getAliasClause() != null 23893 && table.getAliasClause().getColumns() != null) { 23894 for (k = 0; k < columns.size(); k++) { 23895 ResultColumn column = columns.get(k); 23896 List<String> splits = SQLUtil.parseNames(columnName.toString()); 23897 if ("*".equals(column.getName())) { 23898 if (!containsStarColumn(column, columnName)) { 23899 column.bindStarLinkColumn(columnName); 23900 } 23901 relation.addSource(new ResultColumnRelationshipElement(column, columnName)); 23902 } else if (splits.size() > 1 && EDbVendor.dbvbigquery == getOption().getVendor()) { 23903 if (DlineageUtil.compareColumnIdentifier(getColumnName(splits.get(0)), 23904 DlineageUtil.getIdentifierNormalColumnName(column.getName()))) { 23905 if (!column.equals(modelObject)) { 23906 relation.addSource(new ResultColumnRelationshipElement(column, 23907 columnName)); 23908 } 23909 break; 23910 } 23911 } else if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName), 23912 DlineageUtil.getIdentifierNormalColumnName(column.getName()))) { 23913 if (!column.equals(modelObject)) { 23914 relation.addSource( 23915 new ResultColumnRelationshipElement(column, columnName)); 23916 } 23917 break; 23918 } 23919 } 23920 } else if (table.getSubquery() != null || (table.getTableExpr() != null 23921 && table.getTableExpr().getSubQuery() != null)) { 23922 TSelectSqlStatement select = table.getSubquery(); 23923 if (select == null) { 23924 select = table.getTableExpr().getSubQuery(); 23925 } 23926 if (columnName.getSourceTable() != null) { 23927 Object tableModel = modelManager.getModel(columnName.getSourceTable()); 23928 appendResultColumnRelationSource(modelObject, relation, columnIndex, columnName, 23929 tableModel); 23930 } else if (columnName.getObjectToken() != null 23931 && !SQLUtil.isEmpty(table.getAliasName())) { 23932 if (DlineageUtil.compareTableIdentifier(columnName.getObjectToken().toString(), 23933 table.getAliasName())) { 23934 Object tableModel = modelManager.getModel(table); 23935 appendResultColumnRelationSource(modelObject, relation, columnIndex, 23936 columnName, tableModel); 23937 } 23938 } else if(columns!=null) { 23939 for (k = 0; k < columns.size(); k++) { 23940 ResultColumn column = columns.get(k); 23941 List<String> splits = SQLUtil.parseNames(columnName.toString()); 23942 if ("*".equals(column.getName())) { 23943 if (!containsStarColumn(column, columnName)) { 23944 column.bindStarLinkColumn(columnName); 23945 } 23946 relation.addSource(new ResultColumnRelationshipElement(column, columnName)); 23947 } else if (splits.size() > 1 && EDbVendor.dbvbigquery == getOption().getVendor()) { 23948 if (DlineageUtil.compareColumnIdentifier(getColumnName(splits.get(0)), 23949 DlineageUtil.getIdentifierNormalColumnName(column.getName()))) { 23950 if (!column.equals(modelObject)) { 23951 relation.addSource(new ResultColumnRelationshipElement(column, 23952 columnName)); 23953 } 23954 break; 23955 } 23956 } else if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName), 23957 DlineageUtil.getIdentifierNormalColumnName(column.getName()))) { 23958 if (!column.equals(modelObject)) { 23959 relation.addSource( 23960 new ResultColumnRelationshipElement(column, columnName)); 23961 } 23962 break; 23963 } 23964 } 23965 } 23966 } else if (table.getOutputMerge() != null) { 23967 if (columnName.getSourceColumn() != null) { 23968 Object model = modelManager.getModel(columnName.getSourceColumn()); 23969 if (model instanceof ResultColumn) { 23970 ResultColumn resultColumn = (ResultColumn) model; 23971 if ("*".equals(resultColumn.getName()) 23972 && !containsStarColumn(resultColumn, columnName)) { 23973 resultColumn.bindStarLinkColumn(columnName); 23974 } 23975 relation.addSource( 23976 new ResultColumnRelationshipElement(resultColumn, columnName)); 23977 } 23978 } else if (columnName.getSourceTable() != null) { 23979 Object tableModel = modelManager.getModel(columnName.getSourceTable()); 23980 appendResultColumnRelationSource(modelObject, relation, columnIndex, columnName, 23981 tableModel); 23982 } else if (columnName.getObjectToken() != null 23983 && !SQLUtil.isEmpty(table.getAliasName())) { 23984 if (DlineageUtil.compareTableIdentifier(columnName.getObjectToken().toString(), 23985 table.getAliasName())) { 23986 Object tableModel = modelManager.getModel(table); 23987 appendResultColumnRelationSource(modelObject, relation, columnIndex, 23988 columnName, tableModel); 23989 } 23990 } 23991 } 23992 } 23993 } 23994 } 23995 } 23996 } 23997 if (relation.getSources().size() == 0 && isKeyword(columnName)) { 23998 Table constantTable = modelFactory.createConstantsTable(stmtStack.peek()); 23999 TableColumn constantColumn = modelFactory.createTableColumn(constantTable, columnName, true); 24000 relation.addSource(new ConstantRelationshipElement(constantColumn)); 24001 } 24002 24003 if (relation.getSources().size() > 0) { 24004 for (RelationshipElement<?> sourceItem: relation.getSources()) { 24005 Object source = sourceItem.getElement(); 24006 ImpactRelationship impactRelation = null; 24007 if (source instanceof ResultColumn 24008 && !((ResultColumn) source).getResultSet().getRelationRows().getHoldRelations().isEmpty()) { 24009 impactRelation = modelFactory.createImpactRelation(); 24010 impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>( 24011 ((ResultColumn) source).getResultSet().getRelationRows())); 24012 impactRelation.setEffectType(effectType); 24013 } else if (source instanceof TableColumn 24014 && !((TableColumn) source).getTable().getRelationRows().getHoldRelations().isEmpty()) { 24015 impactRelation = modelFactory.createImpactRelation(); 24016 impactRelation.addSource(new RelationRowsRelationshipElement<TableRelationRows>( 24017 ((TableColumn) source).getTable().getRelationRows())); 24018 impactRelation.setEffectType(effectType);; 24019 } 24020 24021 if (impactRelation == null) { 24022 continue; 24023 } 24024 24025 Object target = relation.getTarget().getElement(); 24026 if (target instanceof ResultColumn) { 24027 impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 24028 ((ResultColumn) target).getResultSet().getRelationRows())); 24029 } else if (target instanceof TableColumn) { 24030 impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>( 24031 ((TableColumn) target).getTable().getRelationRows())); 24032 } 24033 24034 if (impactRelation.getSources().iterator().next().getElement() == impactRelation.getTarget().getElement()) { 24035 modelManager.removeRelation(impactRelation); 24036 } 24037 } 24038 } 24039 } 24040 return relation; 24041 } 24042 24043 private boolean isNotInProcedure(Table table) { 24044 TStoredProcedureSqlStatement stmt = getProcedureParent(stmtStack.peek()); 24045 Procedure procedure = this.modelFactory.createProcedure(stmt); 24046 if(procedure!=null && procedure.getName().equals(table.getParent())){ 24047 return false; 24048 } 24049 return true; 24050 } 24051 24052 private boolean hasJoin(TCustomSqlStatement stmt) { 24053 if (stmt.getJoins() == null || stmt.getJoins().size() == 0) 24054 return false; 24055 if (stmt.getJoins().size() > 1) { 24056 return true; 24057 } 24058 TJoinItemList joinItems = stmt.getJoins().getJoin(0).getJoinItems(); 24059 if (joinItems == null || joinItems.size() == 0) { 24060 return false; 24061 } 24062 return true; 24063 } 24064 24065 private boolean isInQuery(TSelectSqlStatement query, TResultColumn column) { 24066 if(query == null) 24067 return false; 24068 TResultColumnList columns = query.getResultColumnList(); 24069 if (columns != null) { 24070 for (int i = 0; i < columns.size(); i++) { 24071 if (columns.getResultColumn(i).equals(column)) { 24072 return true; 24073 } 24074 } 24075 } 24076 return false; 24077 } 24078 24079 private void appendResultColumnRelationSource(Object modelObject, DataFlowRelationship relation, int columnIndex, 24080 TObjectName columnName, Object tableModel) { 24081 if (tableModel instanceof Table) { 24082 Object model = modelManager.getModel(new Pair<Table, TObjectName>((Table) tableModel, columnName)); 24083 if (model instanceof TableColumn) { 24084 relation.addSource(new TableColumnRelationshipElement((TableColumn) model)); 24085 } 24086 } else if (tableModel instanceof ResultSet) { 24087 List<ResultColumn> queryColumns = ((ResultSet) tableModel).getColumns(); 24088 boolean flag = false; 24089 for (int l = 0; l < queryColumns.size(); l++) { 24090 ResultColumn column = queryColumns.get(l); 24091 if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName), 24092 DlineageUtil.getIdentifierNormalColumnName(column.getName()))) { 24093 if (!column.equals(modelObject)) { 24094 relation.addSource(new ResultColumnRelationshipElement(column, columnName)); 24095 flag = true; 24096 } 24097 break; 24098 } 24099 } 24100 if (!flag) { 24101 for (int l = 0; l < queryColumns.size(); l++) { 24102 ResultColumn column = queryColumns.get(l); 24103 if ("*".equals(column.getName())) { 24104 if (!containsStarColumn(column, columnName)) { 24105 column.bindStarLinkColumn(columnName); 24106 } 24107 relation.addSource(new ResultColumnRelationshipElement(column, columnName)); 24108 flag = true; 24109 break; 24110 } 24111 } 24112 } 24113 if (!flag && columnIndex < queryColumns.size() && columnIndex != -1) { 24114 relation.addSource(new ResultColumnRelationshipElement(queryColumns.get(columnIndex), columnName)); 24115 } 24116 } 24117 } 24118 24119 private boolean isApplyJoin(TCustomSqlStatement stmt) { 24120 if (stmt.getJoins() == null || stmt.getJoins().size() == 0) 24121 return false; 24122 TJoinItemList joinItems = stmt.getJoins().getJoin(0).getJoinItems(); 24123 if (joinItems == null || joinItems.size() == 0) { 24124 return false; 24125 } 24126 if (joinItems.getJoinItem(0).getJoinType() == EJoinType.crossapply 24127 || joinItems.getJoinItem(0).getJoinType() == EJoinType.outerapply) 24128 return true; 24129 return false; 24130 } 24131 24132 private boolean containsStarColumn(ResultColumn resultColumn, TObjectName columnName) { 24133 String targetColumnName = getColumnName(columnName); 24134 if (resultColumn.hasStarLinkColumn()) { 24135 return resultColumn.getStarLinkColumns().containsKey(targetColumnName); 24136 } 24137 return false; 24138 } 24139 24140 private void analyzeAggregate(TFunctionCall function, TExpression expr) { 24141 TCustomSqlStatement stmt = stmtStack.peek(); 24142 ResultSet resultSet = (ResultSet) modelManager.getModel(stmt.getResultColumnList()); 24143 if (resultSet == null) { 24144 return; 24145 } 24146 24147 if (expr != null) { 24148 columnsInExpr visitor = new columnsInExpr(); 24149 expr.inOrderTraverse(visitor); 24150 List<TObjectName> objectNames = visitor.getObjectNames(); 24151 for (int j = 0; j < objectNames.size(); j++) { 24152 TObjectName columnName = objectNames.get(j); 24153 24154 if (columnName.getDbObjectType() == EDbObjectType.variable) { 24155 continue; 24156 } 24157 24158 if (columnName.getColumnNameOnly().startsWith("@") 24159 && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) { 24160 continue; 24161 } 24162 24163 if (columnName.getColumnNameOnly().startsWith(":") 24164 && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) { 24165 continue; 24166 } 24167 24168 Object targetModel0 = modelManager.getModel(function.getFunctionName()); 24169 if (targetModel0 == null && function.getFunctionType() == EFunctionType.array_agg_t && modelManager.getModel(function) instanceof Function) { 24170 Function functionModel = (Function) modelManager.getModel(function); 24171 if (functionModel.getColumns().size() == 1) { 24172 targetModel0 = ((Function) functionModel).getColumns().get(0); 24173 } 24174 } 24175 if (!(targetModel0 instanceof ResultColumn)) { 24176 continue; 24177 } 24178 ResultColumn targetResultColumn0 = (ResultColumn) targetModel0; 24179 AbstractRelationship relation = modelFactory.createRecordSetRelation(); 24180 relation.setEffectType(EffectType.function); 24181 relation.setFunction(function.getFunctionName().toString()); 24182 relation.setTarget(new ResultColumnRelationshipElement(targetResultColumn0)); 24183 TTable table = modelManager.getTable(stmt, columnName); 24184 if (table != null) { 24185 if (modelManager.getModel(table) instanceof Table) { 24186 Table tableModel = (Table) modelManager.getModel(table); 24187 if (tableModel != null) { 24188 TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName, false); 24189 if (columnModel != null) { 24190 relation.addSource( 24191 new TableColumnRelationshipElement(columnModel, columnName.getLocation())); 24192 } 24193 } 24194 } else if (modelManager.getModel(table) instanceof QueryTable) { 24195 Object model = modelManager.getModel(columnName.getSourceColumn()); 24196 if (model instanceof ResultColumn) { 24197 ResultColumn resultColumn = (ResultColumn) model; 24198 if (resultColumn != null) { 24199 relation.addSource( 24200 new ResultColumnRelationshipElement(resultColumn, columnName.getLocation())); 24201 } 24202 } 24203 } 24204 } 24205 } 24206 24207 List<TParseTreeNode> functions = visitor.getFunctions(); 24208 for (int j = 0; j < functions.size(); j++) { 24209 TParseTreeNode functionObj = functions.get(j); 24210 Object functionModel = modelManager.getModel(functionObj); 24211 if (functionModel == null) { 24212 functionModel = createFunction(functionObj); 24213 } 24214 if (functionModel instanceof Function) { 24215 Object targetModel1 = modelManager.getModel(function.getFunctionName()); 24216 if (targetModel1 == null && function.getFunctionType() == EFunctionType.array_agg_t && modelManager.getModel(function) instanceof Function) { 24217 Function functionModel1 = (Function) modelManager.getModel(function); 24218 if (functionModel1.getColumns().size() == 1) { 24219 targetModel1 = ((Function) functionModel1).getColumns().get(0); 24220 } 24221 } 24222 if (!(targetModel1 instanceof ResultColumn)) { 24223 continue; 24224 } 24225 ResultColumn targetRC_func = (ResultColumn) targetModel1; 24226 AbstractRelationship relation; 24227 if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString())) { 24228 // relation = modelFactory.createDataFlowRelation(); 24229 relation = modelFactory.createRecordSetRelation(); 24230 } else { 24231 relation = modelFactory.createRecordSetRelation(); 24232 } 24233 relation.setEffectType(EffectType.function); 24234 relation.setFunction(function.getFunctionName().toString()); 24235 relation.setTarget(new ResultColumnRelationshipElement(targetRC_func)); 24236 24237 if (functionObj instanceof TFunctionCall) { 24238 ResultColumn resultColumn = (ResultColumn) modelManager 24239 .getModel(((TFunctionCall) functionObj).getFunctionName()); 24240 if (resultColumn != null) { 24241 ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(resultColumn, 24242 ((TFunctionCall) functionObj).getFunctionName().getLocation()); 24243 relation.addSource(element); 24244 } 24245 } 24246 if (functionObj instanceof TCaseExpression) { 24247 ResultColumn resultColumn = (ResultColumn) modelManager 24248 .getModel(((TCaseExpression) functionObj).getWhenClauseItemList()); 24249 if (resultColumn != null) { 24250 ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(resultColumn); 24251 relation.addSource(element); 24252 } 24253 } 24254 } else if (functionModel instanceof Table) { 24255 Object targetModel2 = modelManager.getModel(function.getFunctionName()); 24256 if (targetModel2 == null && function.getFunctionType() == EFunctionType.array_agg_t && modelManager.getModel(function) instanceof Function) { 24257 Function functionModel1 = (Function) modelManager.getModel(function); 24258 if (functionModel1.getColumns().size() == 1) { 24259 targetModel2 = ((Function) functionModel1).getColumns().get(0); 24260 } 24261 } 24262 if (!(targetModel2 instanceof ResultColumn)) { 24263 continue; 24264 } 24265 ResultColumn targetRC_table = (ResultColumn) targetModel2; 24266 TableColumn tableColumn = modelFactory.createTableColumn((Table) functionModel, 24267 function.getFunctionName(), false); 24268 AbstractRelationship relation; 24269 if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString())) { 24270 // relation = modelFactory.createDataFlowRelation(); 24271 relation = modelFactory.createRecordSetRelation(); 24272 } else { 24273 relation = modelFactory.createRecordSetRelation(); 24274 } 24275 relation.setEffectType(EffectType.function); 24276 relation.setFunction(function.getFunctionName().toString()); 24277 relation.setTarget(new ResultColumnRelationshipElement(targetRC_table)); 24278 TableColumnRelationshipElement element = new TableColumnRelationshipElement(tableColumn); 24279 relation.addSource(element); 24280 } 24281 } 24282 } 24283 24284 if (expr == null || "COUNT".equalsIgnoreCase(function.getFunctionName().toString())) { 24285 if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString()) 24286 // https://e.gitee.com/gudusoft/issues/list?issue=I4L5EO 24287 // 对于非 count() 函数,当有group by clause时, RelationRows 不参与indirect dataflow, 24288 // 让位与group by clause中的column. 24289 || ((TSelectSqlStatement) stmt).getGroupByClause() == null) { 24290 TTableList tables = stmt.getTables(); 24291 if (tables != null) { 24292 for (int i = 0; i < tables.size(); i++) { 24293 TTable table = tables.getTable(i); 24294 if (modelManager.getModel(table) == null && table.getSubquery() == null) { 24295 modelFactory.createTable(table); 24296 } 24297 if (modelManager.getModel(table) instanceof Table) { 24298 Object targetModel3 = modelManager.getModel(function.getFunctionName()); 24299 if (targetModel3 == null && function.getFunctionType() == EFunctionType.array_agg_t && modelManager.getModel(function) instanceof Function) { 24300 Function functionModel = (Function) modelManager.getModel(function); 24301 if (functionModel.getColumns().size() == 1) { 24302 targetModel3 = functionModel.getColumns().get(0); 24303 } 24304 } 24305 if (!(targetModel3 instanceof ResultColumn)) { 24306 continue; 24307 } 24308 ResultColumn targetRC_tbl = (ResultColumn) targetModel3; 24309 Table tableModel = (Table) modelManager.getModel(table); 24310 AbstractRelationship relation; 24311 if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString())) { 24312 // relation = modelFactory.createDataFlowRelation(); 24313 relation = modelFactory.createRecordSetRelation(); 24314 } else { 24315 relation = modelFactory.createRecordSetRelation(); 24316 } 24317 relation.setEffectType(EffectType.function); 24318 relation.setFunction(function.getFunctionName().toString()); 24319 relation.setTarget(new ResultColumnRelationshipElement(targetRC_tbl)); 24320 24321 if (relation instanceof DataFlowRelationship && option.isShowCountTableColumn()) { 24322 List<TExpression> expressions = new ArrayList<TExpression>(); 24323 getFunctionExpressions(expressions, new ArrayList<TExpression>(), function); 24324 for (int j = 0; j < expressions.size(); j++) { 24325 columnsInExpr visitor = new columnsInExpr(); 24326 expressions.get(j).inOrderTraverse(visitor); 24327 List<TObjectName> objectNames = visitor.getObjectNames(); 24328 if (objectNames != null) { 24329 for (TObjectName columnName : objectNames) { 24330 TTable tempTable = modelManager.getTable(stmt, columnName); 24331 if (table.equals(tempTable)) { 24332 TableColumn tableColumn = modelFactory.createTableColumn(tableModel, 24333 columnName, false); 24334 TableColumnRelationshipElement element = new TableColumnRelationshipElement( 24335 tableColumn); 24336 relation.addSource(element); 24337 } 24338 } 24339 } 24340 } 24341 } 24342 if (relation.getSources().size() == 0) { 24343 RelationRowsRelationshipElement element = new RelationRowsRelationshipElement<TableRelationRows>( 24344 tableModel.getRelationRows()); 24345 relation.addSource(element); 24346 } 24347 } else if (modelManager.getModel(table) instanceof QueryTable) { 24348 Object targetModel4 = modelManager.getModel(function.getFunctionName()); 24349 if (targetModel4 == null && function.getFunctionType() == EFunctionType.array_agg_t && modelManager.getModel(function) instanceof Function) { 24350 Function functionModel = (Function) modelManager.getModel(function); 24351 targetModel4 = functionModel.getColumns().get(0); 24352 } 24353 if (!(targetModel4 instanceof ResultColumn)) { 24354 continue; 24355 } 24356 ResultColumn targetRC_qt = (ResultColumn) targetModel4; 24357 QueryTable tableModel = (QueryTable) modelManager.getModel(table); 24358 AbstractRelationship relation; 24359 if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString())) { 24360 // relation = modelFactory.createDataFlowRelation(); 24361 relation = modelFactory.createRecordSetRelation(); 24362 } else { 24363 relation = modelFactory.createRecordSetRelation(); 24364 } 24365 relation.setEffectType(EffectType.function); 24366 relation.setFunction(function.getFunctionName().toString()); 24367 relation.setTarget(new ResultColumnRelationshipElement(targetRC_qt)); 24368 RelationRowsRelationshipElement element = new RelationRowsRelationshipElement<ResultSetRelationRows>( 24369 tableModel.getRelationRows()); 24370 relation.addSource(element); 24371 } 24372 } 24373 } 24374 } 24375 24376 if (stmt.getWhereClause() == null || stmt.getWhereClause().getCondition() == null) { 24377 return; 24378 } 24379 24380 columnsInExpr visitor = new columnsInExpr(); 24381 stmt.getWhereClause().getCondition().inOrderTraverse(visitor); 24382 List<TObjectName> objectNames = visitor.getObjectNames(); 24383 for (int j = 0; j < objectNames.size(); j++) { 24384 TObjectName columnName = objectNames.get(j); 24385 if (columnName.getDbObjectType() == EDbObjectType.variable) { 24386 Variable tableModel; 24387 if (columnName.toString().indexOf(".") != -1) { 24388 List<String> splits = SQLUtil.parseNames(columnName.toString()); 24389 tableModel = modelFactory.createVariable(splits.get(splits.size() - 2)); 24390 } else { 24391 tableModel = modelFactory.createVariable(columnName); 24392 } 24393 tableModel.setCreateTable(true); 24394 tableModel.setSubType(SubType.record); 24395 TObjectName variableProperties = new TObjectName(); 24396 variableProperties.setString("*"); 24397 modelFactory.createTableColumn(tableModel, variableProperties, true); 24398 } 24399 24400// if (columnName.getColumnNameOnly().startsWith("@") 24401// && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) { 24402// continue; 24403// } 24404// 24405// if (columnName.getColumnNameOnly().startsWith(":") && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) { 24406// continue; 24407// } 24408 24409 Object targetModel5 = modelManager.getModel(function.getFunctionName()); 24410 if (targetModel5 == null && function.getFunctionType() == EFunctionType.array_agg_t && modelManager.getModel(function) instanceof Function) { 24411 Function functionModel = (Function) modelManager.getModel(function); 24412 if (functionModel.getColumns().size() == 1) { 24413 targetModel5 = functionModel.getColumns().get(0); 24414 } 24415 } 24416 if (!(targetModel5 instanceof ResultColumn)) { 24417 continue; 24418 } 24419 AbstractRelationship relation = modelFactory.createRecordSetRelation(); 24420 relation.setEffectType(EffectType.function); 24421 relation.setFunction(function.getFunctionName().toString()); 24422 relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) targetModel5)); 24423 24424 TTable table = modelManager.getTable(stmt, columnName); 24425 if (table != null) { 24426 if (modelManager.getModel(table) instanceof Table) { 24427 Table tableModel = (Table) modelManager.getModel(table); 24428 if (tableModel != null) { 24429 TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName, false); 24430 if(columnModel == null) { 24431 continue; 24432 } 24433 relation.addSource( 24434 new TableColumnRelationshipElement(columnModel, columnName.getLocation())); 24435 } 24436 } else if (modelManager.getModel(table) instanceof QueryTable) { 24437 Object model = modelManager.getModel(columnName.getSourceColumn()); 24438 if (model instanceof ResultColumn) { 24439 ResultColumn resultColumn = (ResultColumn) model; 24440 if (resultColumn != null) { 24441 relation.addSource( 24442 new ResultColumnRelationshipElement(resultColumn, columnName.getLocation())); 24443 } 24444 } 24445 } 24446 } 24447 } 24448 } 24449 } 24450 24451 private void analyzeFilterCondition(Object modelObject, TExpression expr, EJoinType joinType, 24452 JoinClauseType joinClauseType, EffectType effectType) { 24453 if (expr == null) { 24454 return; 24455 } 24456 24457 TCustomSqlStatement stmt = stmtStack.peek(); 24458 24459 columnsInExpr visitor = new columnsInExpr(); 24460 expr.inOrderTraverse(visitor); 24461 24462 List<TObjectName> objectNames = visitor.getObjectNames(); 24463 List<TParseTreeNode> functions = visitor.getFunctions(); 24464 List<TResultColumn> resultColumns = visitor.getResultColumns(); 24465 List<TParseTreeNode> constants = visitor.getConstants(); 24466 24467 ImpactRelationship relation = modelFactory.createImpactRelation(); 24468 relation.setEffectType(effectType); 24469 relation.setJoinClauseType(joinClauseType); 24470 if (modelObject instanceof ResultColumn) { 24471 relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) modelObject)); 24472 } else { 24473 ResultSet resultSet = (ResultSet) modelManager.getModel(stmt.getResultColumnList()); 24474 if (resultSet == null && stmt instanceof TUpdateSqlStatement) { 24475 resultSet = (ResultSet) modelManager.getModel(stmt); 24476 } 24477 if (resultSet == null && stmt instanceof TMergeSqlStatement) { 24478 TSelectSqlStatement subquery = ((TMergeSqlStatement) stmt).getUsingTable().getSubquery(); 24479 if (subquery != null) { 24480 resultSet = (ResultSet) modelManager.getModel(((TMergeSqlStatement) stmt).getUsingTable()); 24481 } 24482 else { 24483 resultSet = modelFactory.createQueryTable(((TMergeSqlStatement) stmt).getUsingTable()); 24484 } 24485 } 24486 if (resultSet != null) { 24487 relation.setTarget( 24488 new RelationRowsRelationshipElement<ResultSetRelationRows>(resultSet.getRelationRows())); 24489 } 24490 if (stmt instanceof TDeleteSqlStatement) { 24491 Table table = (Table) modelManager.getModel(((TDeleteSqlStatement) stmt).getTargetTable()); 24492 if (table != null) { 24493 relation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(table.getRelationRows())); 24494 } 24495 } 24496 } 24497 if (relation.getTarget() != null) { 24498 24499 if (constants != null && constants.size() > 0) { 24500 if (option.isShowConstantTable()) { 24501 Table constantTable = modelFactory.createConstantsTable(stmtStack.peek()); 24502 for (int i = 0; i < constants.size(); i++) { 24503 TParseTreeNode constant = constants.get(i); 24504 if (constant instanceof TConstant) { 24505 TableColumn constantColumn = modelFactory.createTableColumn(constantTable, 24506 (TConstant) constant); 24507 relation.addSource(new ConstantRelationshipElement(constantColumn)); 24508 } else if (constant instanceof TObjectName) { 24509 TableColumn constantColumn = modelFactory.createTableColumn(constantTable, 24510 (TObjectName) constant, false); 24511 if(constantColumn == null) { 24512 continue; 24513 } 24514 relation.addSource(new ConstantRelationshipElement(constantColumn)); 24515 } 24516 } 24517 } 24518 } 24519 24520 for (int j = 0; j < objectNames.size(); j++) { 24521 TObjectName columnName = objectNames.get(j); 24522 if (columnName.getDbObjectType() == EDbObjectType.variable) { 24523 Variable variable = modelFactory.createVariable(columnName); 24524 variable.setSubType(SubType.record); 24525 if (variable.getColumns().isEmpty()) { 24526 TObjectName variableProperties = new TObjectName(); 24527 variableProperties.setString("*"); 24528 modelFactory.createTableColumn(variable, variableProperties, true); 24529 } 24530 relation.addSource(new TableColumnRelationshipElement(variable.getColumns().get(0), columnName.getLocation())); 24531 continue; 24532 } 24533 24534 if (columnName.getColumnNameOnly().startsWith("@") 24535 && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) { 24536 continue; 24537 } 24538 24539 if (columnName.getColumnNameOnly().startsWith(":") 24540 && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) { 24541 continue; 24542 } 24543 24544 TTable table = modelManager.getTable(stmt, columnName); 24545 24546 if (table == null) { 24547 table = columnName.getSourceTable(); 24548 } 24549 24550 if (table == null && stmt.tables != null) { 24551 for (int k = 0; k < stmt.tables.size(); k++) { 24552 if (table != null) 24553 break; 24554 24555 TTable tTable = stmt.tables.getTable(k); 24556 if (tTable.getTableType().name().startsWith("open")) { 24557 continue; 24558 } else if (getTableLinkedColumns(tTable) != null && getTableLinkedColumns(tTable).size() > 0) { 24559 for (int z = 0; z < getTableLinkedColumns(tTable).size(); z++) { 24560 TObjectName refer = getTableLinkedColumns(tTable).getObjectName(z); 24561 if ("*".equals(getColumnName(refer))) 24562 continue; 24563 if (getColumnName(refer).equals(getColumnName(columnName))) { 24564 table = tTable; 24565 break; 24566 } 24567 } 24568 } else if (columnName.getTableToken() != null 24569 && (columnName.getTableToken().getAstext().equalsIgnoreCase(tTable.getName()) 24570 || columnName.getTableToken().getAstext().equalsIgnoreCase(tTable.getAliasName()))) { 24571 table = tTable; 24572 break; 24573 } 24574 } 24575 24576 if (table == null) { 24577 for (int k = 0; k < stmt.tables.size(); k++) { 24578 if (table != null) 24579 break; 24580 24581 TTable tTable = stmt.tables.getTable(k); 24582 Object model = ModelBindingManager.get().getModel(tTable); 24583 if (model instanceof Table) { 24584 Table tableModel = (Table) model; 24585 for (int z = 0; tableModel.getColumns() != null 24586 && z < tableModel.getColumns().size(); z++) { 24587 TableColumn refer = tableModel.getColumns().get(z); 24588 if (getColumnName(refer.getName()).equals(getColumnName(columnName))) { 24589 table = tTable; 24590 break; 24591 } 24592 if (refer.hasStarLinkColumn()) { 24593 for (TObjectName linkColumn : refer.getStarLinkColumnList()) { 24594 if (getColumnName(linkColumn).equals(getColumnName(columnName))) { 24595 table = tTable; 24596 break; 24597 } 24598 } 24599 } 24600 } 24601 } else if (model instanceof QueryTable) { 24602 QueryTable tableModel = (QueryTable) model; 24603 for (int z = 0; tableModel.getColumns() != null 24604 && z < tableModel.getColumns().size(); z++) { 24605 ResultColumn refer = tableModel.getColumns().get(z); 24606 if (DlineageUtil.getIdentifierNormalColumnName(refer.getName()).equals( 24607 DlineageUtil.getIdentifierNormalColumnName(getColumnName(columnName)))) { 24608 table = tTable; 24609 break; 24610 } 24611 if (refer.hasStarLinkColumn()) { 24612 for (TObjectName linkColumn : refer.getStarLinkColumnList()) { 24613 if (getColumnName(linkColumn).equals(getColumnName(columnName))) { 24614 table = tTable; 24615 break; 24616 } 24617 } 24618 } 24619 } 24620 } 24621 } 24622 } 24623 } 24624 24625 if (table == null && stmt.tables != null && stmt.tables.size() != 0 24626 && !(isBuiltInFunctionName(columnName) && isFromFunction(columnName))) { 24627 24628 if (modelManager.getModel(stmt) instanceof ResultSet) { 24629 ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt); 24630 boolean find = false; 24631 for (ResultColumn resultColumn : resultSetModel.getColumns()) { 24632 if(resultColumn.equals(modelObject)) { 24633 continue; 24634 } 24635 if (!TSQLEnv.isAliasReferenceForbidden.get(option.getVendor())) { 24636 if (getColumnName(columnName).equals(getColumnName(resultColumn.getName()))) { 24637 if (resultColumn.getColumnObject() != null) { 24638 int startToken = resultColumn.getColumnObject().getStartToken().posinlist; 24639 int endToken = resultColumn.getColumnObject().getEndToken().posinlist; 24640 if (columnName.getStartToken().posinlist >= startToken 24641 && columnName.getEndToken().posinlist <= endToken) { 24642 continue; 24643 } 24644 } 24645 relation.addSource(new ResultColumnRelationshipElement(resultColumn)); 24646 find = true; 24647 break; 24648 } 24649 } 24650 } 24651 if (find) { 24652 continue; 24653 } 24654 } 24655 24656 TObjectName pseudoTableName = new TObjectName(); 24657 // Use qualified prefix from column name if available (e.g., sch.pk_constv2 from sch.pk_constv2.c_cdsl) 24658 // Otherwise fall back to default pseudo table name 24659 String qualifiedPrefix = getQualifiedPrefixFromColumn(columnName); 24660 pseudoTableName.setString(qualifiedPrefix != null ? qualifiedPrefix : "pseudo_table_include_orphan_column"); 24661 Table pseudoTable = modelFactory.createTableByName(pseudoTableName); 24662 pseudoTable.setPseudo(true); 24663 TableColumn pseudoTableColumn = modelFactory.createTableColumn(pseudoTable, columnName, true); 24664 24665 // If not linking to first table and column has qualified prefix (3-part name like sch.pkg.col), 24666 // add the pseudo table column as source 24667 if (!isLinkOrphanColumnToFirstTable() && pseudoTableColumn != null && qualifiedPrefix != null) { 24668 relation.addSource(new TableColumnRelationshipElement(pseudoTableColumn)); 24669 } 24670 24671 if (isLinkOrphanColumnToFirstTable()) { 24672 TTable orphanTable = stmt.tables.getTable(0); 24673 table = stmt.tables.getTable(0); 24674 Object tableModel = modelManager.getModel(table); 24675 if (tableModel == null) { 24676 tableModel = modelFactory.createTable(orphanTable); 24677 } 24678 if (tableModel instanceof Table) { 24679 modelFactory.createTableColumn((Table) tableModel, columnName, false); 24680 ErrorInfo errorInfo = new ErrorInfo(); 24681 errorInfo.setErrorType(ErrorInfo.LINK_ORPHAN_COLUMN); 24682 errorInfo.setErrorMessage("Link orphan column [" + columnName.toString() 24683 + "] to the first table [" + orphanTable.getFullNameWithAliasString() + "]"); 24684 errorInfo.setStartPosition(new Pair3<Long, Long, String>(columnName.getStartToken().lineNo, 24685 columnName.getStartToken().columnNo, ModelBindingManager.getGlobalHash())); 24686 errorInfo.setEndPosition(new Pair3<Long, Long, String>(columnName.getEndToken().lineNo, 24687 columnName.getEndToken().columnNo + columnName.getEndToken().getAstext().length(), 24688 ModelBindingManager.getGlobalHash())); 24689 errorInfo.fillInfo(this); 24690 errorInfos.add(errorInfo); 24691 } 24692 } 24693 } 24694 24695 if (table != null) { 24696 if (modelManager.getModel(table) instanceof Table) { 24697 Table tableModel = (Table) modelManager.getModel(table); 24698 if (tableModel != null) { 24699 TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName, false); 24700 if(columnModel!=null) { 24701 TableColumnRelationshipElement element = new TableColumnRelationshipElement(columnModel, 24702 columnName.getLocation()); 24703 relation.addSource(element); 24704 } 24705 } 24706 } else if (modelManager.getModel(table) instanceof QueryTable) { 24707 QueryTable tableModel = (QueryTable)modelManager.getModel(table); 24708 if (table.getSubquery() != null && table.getSubquery().isCombinedQuery()) { 24709 TSelectSqlStatement subquery = table.getSubquery(); 24710 List<ResultSet> resultSets = new ArrayList<ResultSet>(); 24711 if (!subquery.getLeftStmt().isCombinedQuery()) { 24712 ResultSet sourceResultSet = (ResultSet) modelManager 24713 .getModel(subquery.getLeftStmt().getResultColumnList()); 24714 resultSets.add(sourceResultSet); 24715 } else { 24716 ResultSet sourceResultSet = (ResultSet) modelManager.getModel(subquery.getLeftStmt()); 24717 resultSets.add(sourceResultSet); 24718 } 24719 24720 if (!subquery.getRightStmt().isCombinedQuery()) { 24721 ResultSet sourceResultSet = (ResultSet) modelManager 24722 .getModel(subquery.getRightStmt().getResultColumnList()); 24723 resultSets.add(sourceResultSet); 24724 } else { 24725 ResultSet sourceResultSet = (ResultSet) modelManager.getModel(subquery.getRightStmt()); 24726 resultSets.add(sourceResultSet); 24727 } 24728 24729 for (ResultSet sourceResultSet : resultSets) { 24730 if (sourceResultSet != null && columnName.getSourceColumn() != null) { 24731 for (int k = 0; k < sourceResultSet.getColumns().size(); k++) { 24732 if (getColumnName(sourceResultSet.getColumns().get(k).getName()).equals( 24733 getColumnName(columnName.getSourceColumn().getColumnNameOnly()))) { 24734 Set<TObjectName> starLinkColumnSet = sourceResultSet.getColumns().get(k) 24735 .getStarLinkColumns().get(getColumnName(columnName)); 24736 if (starLinkColumnSet != null && !starLinkColumnSet.isEmpty()) { 24737 ResultColumn column = modelFactory.createResultColumn(sourceResultSet, 24738 starLinkColumnSet.iterator().next(), true); 24739 relation.addSource(new ResultColumnRelationshipElement(column)); 24740 } else { 24741 relation.addSource(new ResultColumnRelationshipElement( 24742 sourceResultSet.getColumns().get(k))); 24743 } 24744 } 24745 } 24746 } 24747 } 24748 } else { 24749 Object model = modelManager.getModel(columnName.getSourceColumn()); 24750 if (model instanceof ResultColumn) { 24751 ResultColumn resultColumn = (ResultColumn) model; 24752 if (resultColumn != null) { 24753 if (resultColumn.hasStarLinkColumn()) { 24754 Set<TObjectName> starLinkColumnSet = resultColumn.getStarLinkColumns() 24755 .get(getColumnName(columnName)); 24756 if (starLinkColumnSet != null && !starLinkColumnSet.isEmpty()) { 24757 ResultColumn column = modelFactory.createResultColumn( 24758 resultColumn.getResultSet(), starLinkColumnSet.iterator().next(), true); 24759 relation.addSource(new ResultColumnRelationshipElement(column)); 24760 } else { 24761 resultColumn.bindStarLinkColumn(columnName); 24762 ResultColumn column = modelFactory 24763 .createResultColumn(resultColumn.getResultSet(), columnName, true); 24764 relation.addSource(new ResultColumnRelationshipElement(column)); 24765 } 24766 } else { 24767 ResultColumnRelationshipElement element = new ResultColumnRelationshipElement( 24768 resultColumn, columnName.getLocation()); 24769 relation.addSource(element); 24770 } 24771 } 24772 } 24773 else{ 24774 boolean find = false; 24775 for (int i = 0; i < tableModel.getColumns().size(); i++) { 24776 ResultColumn resultColumn = tableModel.getColumns().get(i); 24777 if (DlineageUtil.getIdentifierNormalColumnName(resultColumn.getName()).equals( 24778 DlineageUtil.getIdentifierNormalColumnName(getColumnName(columnName)))) { 24779 ResultColumnRelationshipElement element = new ResultColumnRelationshipElement( 24780 resultColumn, columnName.getLocation()); 24781 relation.addSource(element); 24782 find = true; 24783 break; 24784 } 24785 else if (resultColumn.getName().endsWith("*")) { 24786 resultColumn.bindStarLinkColumn(columnName); 24787 } 24788 } 24789 if(!find){ 24790 ResultColumn resultColumn = new ResultColumn(tableModel, columnName); 24791 ResultColumnRelationshipElement element = new ResultColumnRelationshipElement( 24792 resultColumn, columnName.getLocation()); 24793 relation.addSource(element); 24794 } 24795 } 24796 } 24797 } 24798 } 24799 } 24800 24801 for (int j = 0; j < functions.size(); j++) { 24802 TParseTreeNode functionObj = functions.get(j); 24803 Object functionModel = modelManager.getModel(functionObj); 24804 if (functionModel == null) { 24805 functionModel = createFunction(functionObj); 24806 } 24807 if (functionModel instanceof Function) { 24808 if (functionObj instanceof TFunctionCall) { 24809 ResultColumn resultColumn = (ResultColumn) modelManager 24810 .getModel(((TFunctionCall) functionObj).getFunctionName()); 24811 if (resultColumn != null) { 24812 ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(resultColumn, 24813 ((TFunctionCall) functionObj).getFunctionName().getLocation()); 24814 relation.addSource(element); 24815 } 24816 } 24817 if (functionObj instanceof TCaseExpression) { 24818 ResultColumn resultColumn = (ResultColumn) modelManager 24819 .getModel(((TCaseExpression) functionObj).getWhenClauseItemList()); 24820 if (resultColumn != null) { 24821 ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(resultColumn); 24822 relation.addSource(element); 24823 } 24824 } 24825 } else if (functionModel instanceof Table) { 24826 TableColumn tableColumn = modelFactory.createTableColumn((Table) functionModel, 24827 ((TFunctionCall) functionObj).getFunctionName(), false); 24828 TableColumnRelationshipElement element = new TableColumnRelationshipElement(tableColumn); 24829 relation.addSource(element); 24830 } 24831 } 24832 24833 for (int j = 0; j < resultColumns.size(); j++) { 24834 TResultColumn resultColumn = resultColumns.get(j); 24835 if (modelManager.getModel(resultColumn) instanceof ResultColumn) { 24836 ResultColumn resultColumnModel = (ResultColumn) modelManager.getModel(resultColumn); 24837 relation.addSource(new ResultColumnRelationshipElement(resultColumnModel, ESqlClause.selectList)); 24838 } 24839 } 24840 } 24841 24842 if (isShowJoin() && joinClauseType != null) { 24843 joinInExpr joinVisitor = new joinInExpr(joinType, joinClauseType, effectType); 24844 expr.inOrderTraverse(joinVisitor); 24845 } 24846 } 24847 24848 public void dispose() { 24849 accessedSubqueries.clear(); 24850 accessedStatements.clear(); 24851 stmtStack.clear(); 24852 viewDDLMap.clear(); 24853 procedureDDLMap.clear(); 24854 structObjectMap.clear(); 24855 appendResultSets.clear(); 24856 appendStarColumns.clear(); 24857 appendTableStarColumns.clear(); 24858 modelManager.DISPLAY_ID.clear(); 24859 modelManager.DISPLAY_NAME.clear(); 24860 tableIds.clear(); 24861 ModelBindingManager.remove(); 24862 } 24863 24864 class joinTreatColumnsInExpr implements IExpressionVisitor { 24865 24866 private List<TObjectName> objectNames = new ArrayList<TObjectName>(); 24867 24868 private TTable table; 24869 24870 public joinTreatColumnsInExpr(TTable table) { 24871 this.table = table; 24872 } 24873 24874 public List<TObjectName> getObjectNames() { 24875 return objectNames; 24876 } 24877 24878 boolean is_compare_condition(EExpressionType t) { 24879 return t == EExpressionType.simple_comparison_t; 24880 } 24881 24882 @Override 24883 public boolean exprVisit(TParseTreeNode pNode, boolean isLeafNode) { 24884 TExpression expr = (TExpression) pNode; 24885 if (is_compare_condition(expr.getExpressionType())) { 24886 TExpression leftExpr = expr.getLeftOperand(); 24887 columnsInExpr leftVisitor = new columnsInExpr(); 24888 leftExpr.inOrderTraverse(leftVisitor); 24889 List<TObjectName> leftObjectNames = leftVisitor.getObjectNames(); 24890 24891 TExpression rightExpr = expr.getRightOperand(); 24892 columnsInExpr rightVisitor = new columnsInExpr(); 24893 rightExpr.inOrderTraverse(rightVisitor); 24894 List<TObjectName> rightObjectNames = rightVisitor.getObjectNames(); 24895 24896 if (!leftObjectNames.isEmpty() && !rightObjectNames.isEmpty()) { 24897 for (TObjectName column : leftObjectNames) { 24898 if (column.getSourceTable() != null && column.getSourceTable().equals(table)) { 24899 objectNames.add(column); 24900 return false; 24901 } 24902 } 24903 for (TObjectName column : rightObjectNames) { 24904 if (column.getSourceTable() != null && column.getSourceTable().equals(table)) { 24905 objectNames.add(column); 24906 return false; 24907 } 24908 } 24909 } 24910 return false; 24911 } 24912 return true; 24913 } 24914 } 24915 24916 class columnsInExpr implements IExpressionVisitor { 24917 24918 private List<TParseTreeNode> constants = new ArrayList<TParseTreeNode>(); 24919 private List<TObjectName> objectNames = new ArrayList<TObjectName>(); 24920 private List<TParseTreeNode> functions = new ArrayList<TParseTreeNode>(); 24921 private List<TResultColumn> resultColumns = new ArrayList<TResultColumn>(); 24922 private List<TSelectSqlStatement> subquerys = new ArrayList<TSelectSqlStatement>(); 24923 private boolean skipFunction = false; 24924 24925 public void setSkipFunction(boolean skipFunction) { 24926 this.skipFunction = skipFunction; 24927 } 24928 24929 public List<TParseTreeNode> getFunctions() { 24930 return functions; 24931 } 24932 24933 public List<TSelectSqlStatement> getSubquerys() { 24934 return subquerys; 24935 } 24936 24937 public List<TParseTreeNode> getConstants() { 24938 return constants; 24939 } 24940 24941 public List<TObjectName> getObjectNames() { 24942 return objectNames; 24943 } 24944 24945 public List<TResultColumn> getResultColumns() { 24946 return resultColumns; 24947 } 24948 24949 @Override 24950 public boolean exprVisit(TParseTreeNode pNode, boolean isLeafNode) { 24951 TExpression lcexpr = (TExpression) pNode; 24952 // Handle named argument expressions (e.g., "INPUT => value" in Snowflake FLATTEN) 24953 // The left operand is the parameter name, NOT a column reference. 24954 // Only traverse the right operand (the value). 24955 if (lcexpr.getExpressionType() == EExpressionType.assignment_t) { 24956 // Skip left operand (parameter name) - only traverse right operand (value) 24957 if (lcexpr.getRightOperand() != null) { 24958 lcexpr.getRightOperand().inOrderTraverse(this); 24959 } 24960 return false; // Don't continue default traversal 24961 } 24962 if (lcexpr.getExpressionType() == EExpressionType.simple_constant_t) { 24963 if (lcexpr.getConstantOperand() != null) { 24964 if(lcexpr.getConstantOperand().getInt64_expression()!=null 24965 && lcexpr.getConstantOperand().getInt64_expression().getExpressionType() == EExpressionType.function_t) { 24966 lcexpr.getConstantOperand().getInt64_expression().inOrderTraverse(this); 24967 } 24968 else { 24969 constants.add(lcexpr.getConstantOperand()); 24970 } 24971 } 24972 } else if (lcexpr.getExpressionType() == EExpressionType.array_t) { 24973 if(lcexpr.getObjectOperand()!=null) { 24974 TObjectName object = lcexpr.getObjectOperand(); 24975 objectNames.add(object); 24976 } else if (lcexpr.getExprList() != null) { 24977 for (int j = 0; j < lcexpr.getExprList().size(); j++) { 24978 TExpression expr = lcexpr.getExprList().getExpression(j); 24979 if (expr != null) 24980 expr.inOrderTraverse(this); 24981 } 24982 } 24983 } else if (lcexpr.getExpressionType() == EExpressionType.simple_object_name_t) { 24984 if (lcexpr.getObjectOperand() != null && !(isBuiltInFunctionName(lcexpr.getObjectOperand()) 24985 && isFromFunction(lcexpr.getObjectOperand()))) { 24986 TObjectName object = lcexpr.getObjectOperand(); 24987 // Skip named argument parameter names (e.g., INPUT in "INPUT => value") 24988 // These are function parameter names, NOT column references 24989 if (object.getObjectType() == TObjectName.ttobjNamedArgParameter) { 24990 // Skip - this is a named argument parameter name 24991 } else if (object.getDbObjectType() == EDbObjectType.column 24992 || object.getDbObjectType() == EDbObjectType.column_alias 24993 || object.getDbObjectType() == EDbObjectType.alias 24994 || object.getDbObjectType() == EDbObjectType.unknown 24995 || object.getDbObjectType() == EDbObjectType.variable) { 24996 objectNames.add(object); 24997 } else if (object.getDbObjectType() == EDbObjectType.notAColumn 24998 || object.getDbObjectType() == EDbObjectType.date_time_part ) { 24999 constants.add(object); 25000 } 25001 } 25002 } else if (lcexpr.getExpressionType() == EExpressionType.between_t) { 25003 if (lcexpr.getBetweenOperand() != null && lcexpr.getBetweenOperand().getObjectOperand() != null) { 25004 TObjectName object = lcexpr.getBetweenOperand().getObjectOperand(); 25005 if (object.getDbObjectType() == EDbObjectType.column 25006 || object.getDbObjectType() == EDbObjectType.column_alias 25007 || object.getDbObjectType() == EDbObjectType.alias 25008 || object.getDbObjectType() == EDbObjectType.unknown 25009 || object.getDbObjectType() == EDbObjectType.variable) { 25010 objectNames.add(object); 25011 } 25012 } 25013 } else if (lcexpr.getExpressionType() == EExpressionType.object_access_t) { 25014 if (lcexpr.getObjectAccess() != null) { 25015 TObjectNameList objects = lcexpr.getObjectAccess().getAttributes(); 25016 TFunctionCall function = lcexpr.getObjectAccess().getObjectExpr().getFunctionCall(); 25017 if (objects != null && function != null) { 25018 for (TObjectName object : objects) { 25019 TGSqlParser sqlparser = new TGSqlParser(option.getVendor()); 25020 sqlparser.sqltext = "select " + function.getFunctionName().toString() + "." 25021 + object.getColumnNameOnly() + " from " + function.getFunctionName().toString(); 25022 if (sqlparser.parse() == 0) { 25023 TObjectName objectName = sqlparser.sqlstatements.get(0).getResultColumnList() 25024 .getResultColumn(0).getFieldAttr(); 25025 objectNames.add(objectName); 25026 } 25027 } 25028 } 25029 } 25030 } else if (lcexpr.getExpressionType() == EExpressionType.function_t || lcexpr.getExpressionType() == EExpressionType.fieldselection_t) { 25031 TFunctionCall func = lcexpr.getFunctionCall(); 25032 if (func == null) { 25033 return true; 25034 } 25035 if (skipFunction) { 25036 if (func.getArgs() != null) { 25037 for (int k = 0; k < func.getArgs().size(); k++) { 25038 TExpression expr = func.getArgs().getExpression(k); 25039 if (expr != null) 25040 expr.inOrderTraverse(this); 25041 } 25042 } 25043 25044 if (func.getTrimArgument() != null) { 25045 TTrimArgument args = func.getTrimArgument(); 25046 TExpression expr = args.getStringExpression(); 25047 if (expr != null) { 25048 expr.inOrderTraverse(this); 25049 } 25050 expr = args.getTrimCharacter(); 25051 if (expr != null) { 25052 expr.inOrderTraverse(this); 25053 } 25054 } 25055 25056 if (func.getAgainstExpr() != null) { 25057 func.getAgainstExpr().inOrderTraverse(this); 25058 } 25059// if (func.getBetweenExpr() != null) { 25060// func.getBetweenExpr().inOrderTraverse(this); 25061// } 25062 if (func.getExpr1() != null) { 25063 func.getExpr1().inOrderTraverse(this); 25064 } 25065 if (func.getExpr2() != null) { 25066 func.getExpr2().inOrderTraverse(this); 25067 } 25068 if (func.getExpr3() != null) { 25069 func.getExpr3().inOrderTraverse(this); 25070 } 25071 if (func.getParameter() != null) { 25072 func.getParameter().inOrderTraverse(this); 25073 } 25074 } else { 25075 functions.add(func); 25076 } 25077 25078 } else if (lcexpr.getExpressionType() == EExpressionType.case_t) { 25079 TCaseExpression expr = lcexpr.getCaseExpression(); 25080 if (skipFunction) { 25081 TExpression defaultExpr = expr.getElse_expr(); 25082 if (defaultExpr != null) { 25083 defaultExpr.inOrderTraverse(this); 25084 } 25085 TWhenClauseItemList list = expr.getWhenClauseItemList(); 25086 for (int i = 0; i < list.size(); i++) { 25087 TWhenClauseItem element = (TWhenClauseItem) list.getElement(i); 25088 (((TWhenClauseItem) element).getReturn_expr()).inOrderTraverse(this); 25089 25090 } 25091 } else { 25092 functions.add(expr); 25093 } 25094 } else if (lcexpr.getSubQuery() != null) { 25095 TSelectSqlStatement select = lcexpr.getSubQuery(); 25096 analyzeSelectStmt(select); 25097 subquerys.add(select); 25098 if (select.getResultColumnList() != null && select.getResultColumnList().size() > 0) { 25099 for (TResultColumn column : select.getResultColumnList()) { 25100 resultColumns.add(column); 25101 } 25102 } 25103 } 25104 return true; 25105 } 25106 } 25107 25108 class joinInExpr implements IExpressionVisitor { 25109 25110 private EJoinType joinType; 25111 private JoinClauseType joinClauseType; 25112 private EffectType effectType; 25113 25114 public joinInExpr(EJoinType joinType, JoinClauseType joinClauseType, EffectType effectType) { 25115 this.joinType = joinType; 25116 this.joinClauseType = joinClauseType; 25117 this.effectType = effectType; 25118 } 25119 25120 boolean is_compare_condition(EExpressionType t) { 25121 return ((t == EExpressionType.simple_comparison_t) || (t == EExpressionType.group_comparison_t) 25122 || (t == EExpressionType.in_t) || (t == EExpressionType.pattern_matching_t) 25123 || (t == EExpressionType.left_join_t) || (t == EExpressionType.right_join_t)); 25124 } 25125 25126 @Override 25127 public boolean exprVisit(TParseTreeNode pNode, boolean isLeafNode) { 25128 TExpression expr = (TExpression) pNode; 25129 if (is_compare_condition(expr.getExpressionType())) { 25130 TExpression leftExpr = expr.getLeftOperand(); 25131 columnsInExpr leftVisitor = new columnsInExpr(); 25132 leftExpr.inOrderTraverse(leftVisitor); 25133 List<TObjectName> leftObjectNames = leftVisitor.getObjectNames(); 25134 List<TParseTreeNode> leftObjects = leftVisitor.getFunctions(); 25135 leftObjects.addAll(leftObjectNames); 25136 25137 TExpression rightExpr = expr.getRightOperand(); 25138 columnsInExpr rightVisitor = new columnsInExpr(); 25139 rightExpr.inOrderTraverse(rightVisitor); 25140 List<TObjectName> rightObjectNames = rightVisitor.getObjectNames(); 25141 List<TParseTreeNode> rightObjects = rightVisitor.getFunctions(); 25142 rightObjects.addAll(rightObjectNames); 25143 25144 if (!leftObjects.isEmpty() && !rightObjects.isEmpty()) { 25145 TCustomSqlStatement stmt = stmtStack.peek(); 25146 25147 for (int i = 0; i < leftObjects.size(); i++) { 25148 TParseTreeNode leftObject = leftObjects.get(i); 25149 TTable leftTable = null; 25150 TFunctionCall leftFunction = null; 25151 TObjectName leftObjectName = null; 25152 if (leftObject instanceof TObjectName) { 25153 leftObjectName = (TObjectName)leftObject; 25154 25155 if (leftObjectName.getDbObjectType() == EDbObjectType.variable) { 25156 continue; 25157 } 25158 25159 if (leftObjectName.getColumnNameOnly().startsWith("@") 25160 && (option.getVendor() == EDbVendor.dbvmssql 25161 || option.getVendor() == EDbVendor.dbvazuresql)) { 25162 continue; 25163 } 25164 25165 if (leftObjectName.getColumnNameOnly().startsWith(":") 25166 && (option.getVendor() == EDbVendor.dbvhana 25167 || option.getVendor() == EDbVendor.dbvteradata)) { 25168 continue; 25169 } 25170 25171 leftTable = modelManager.getTable(stmt, leftObjectName); 25172 25173 if (leftTable == null) { 25174 leftTable = leftObjectName.getSourceTable(); 25175 } 25176 25177 if (leftTable == null) { 25178 leftTable = modelManager.guessTable(stmt, leftObjectName); 25179 } 25180 } 25181 else if(leftObject instanceof TFunctionCall){ 25182 leftFunction = (TFunctionCall)leftObject; 25183 } 25184 25185 if (leftTable != null || leftFunction != null) { 25186 for (int j = 0; j < rightObjects.size(); j++) { 25187 JoinRelationship joinRelation = modelFactory.createJoinRelation(); 25188 joinRelation.setEffectType(effectType); 25189 if (joinType != null) { 25190 joinRelation.setJoinType(joinType); 25191 } else { 25192 if (expr.getLeftOperand().isOracleOuterJoin()) { 25193 joinRelation.setJoinType(right); 25194 } else if (expr.getRightOperand().isOracleOuterJoin()) { 25195 joinRelation.setJoinType(EJoinType.left); 25196 } else if (expr.getExpressionType() == EExpressionType.left_join_t) { 25197 joinRelation.setJoinType(EJoinType.left); 25198 } else if (expr.getExpressionType() == EExpressionType.right_join_t) { 25199 joinRelation.setJoinType(right); 25200 } else { 25201 joinRelation.setJoinType(EJoinType.inner); 25202 } 25203 } 25204 25205 joinRelation.setJoinClauseType(joinClauseType); 25206 joinRelation.setJoinCondition(expr.toString()); 25207 25208 25209 if (leftTable != null) { 25210 if (modelManager.getModel(leftTable) instanceof Table) { 25211 Table tableModel = (Table) modelManager.getModel(leftTable); 25212 if (tableModel != null) { 25213 TableColumn columnModel = modelFactory.createTableColumn(tableModel, 25214 leftObjectName, false); 25215 if (columnModel != null) { 25216 joinRelation.addSource(new TableColumnRelationshipElement(columnModel)); 25217 } 25218 } 25219 } else if (modelManager.getModel(leftTable) instanceof QueryTable) { 25220 QueryTable table = (QueryTable) modelManager.getModel(leftTable); 25221 TSelectSqlStatement subquery = table.getTableObject().getSubquery(); 25222 if (subquery != null && subquery.isCombinedQuery()) { 25223 ResultColumn resultColumn = matchResultColumn(table.getColumns(), 25224 leftObjectName); 25225 if (resultColumn != null) { 25226 joinRelation 25227 .addSource(new ResultColumnRelationshipElement(resultColumn)); 25228 } 25229 } else if (leftObjectName.getSourceColumn() != null) { 25230 Object model = modelManager.getModel(leftObjectName); 25231 if (model == null) { 25232 model = modelFactory.createResultColumn(table, leftObjectName); 25233 } 25234 if (model instanceof ResultColumn) { 25235 ResultColumn resultColumn = (ResultColumn) model; 25236 if (resultColumn != null) { 25237 joinRelation.addSource( 25238 new ResultColumnRelationshipElement(resultColumn)); 25239 } 25240 } else if (model instanceof LinkedHashMap) { 25241 String columnName = getColumnNameOnly(leftObjectName.toString()); 25242 LinkedHashMap<String, ResultColumn> resultColumns = (LinkedHashMap<String, ResultColumn>) model; 25243 if (resultColumns.containsKey(columnName)) { 25244 ResultColumn resultColumn = resultColumns.get(columnName); 25245 joinRelation.addSource( 25246 new ResultColumnRelationshipElement(resultColumn)); 25247 } 25248 } 25249 } else { 25250 ResultColumn resultColumn = matchResultColumn(table.getColumns(), 25251 leftObjectName); 25252 if (resultColumn != null) { 25253 joinRelation 25254 .addSource(new ResultColumnRelationshipElement(resultColumn)); 25255 } 25256 } 25257 } 25258 } 25259 else if(leftFunction!=null) { 25260 Object functionObj = createFunction(leftFunction); 25261 if(functionObj instanceof Function) { 25262 Function function = (Function)functionObj; 25263 joinRelation.addSource(new ResultColumnRelationshipElement(function.getColumns().get(0))); 25264 } 25265 } 25266 25267 TParseTreeNode rightObject = rightObjects.get(j); 25268 if(rightObject instanceof TObjectName) { 25269 TObjectName rightObjectName = (TObjectName)rightObject; 25270 25271 if (rightObjectName.getDbObjectType() == EDbObjectType.variable) { 25272 continue; 25273 } 25274 25275 if (rightObjectName.getColumnNameOnly().startsWith("@") 25276 && (option.getVendor() == EDbVendor.dbvmssql 25277 || option.getVendor() == EDbVendor.dbvazuresql)) { 25278 continue; 25279 } 25280 25281 if (rightObjectName.getColumnNameOnly().startsWith(":") 25282 && (option.getVendor() == EDbVendor.dbvhana 25283 || option.getVendor() == EDbVendor.dbvteradata)) { 25284 continue; 25285 } 25286 25287 TTable rightTable = modelManager.getTable(stmt, rightObjectName); 25288 if (rightTable == null) { 25289 rightTable = rightObjectName.getSourceTable(); 25290 } 25291 25292 if (rightTable == null) { 25293 rightTable = modelManager.guessTable(stmt, rightObjectName); 25294 } 25295 25296 if (modelManager.getModel(rightTable) instanceof Table) { 25297 Table tableModel = (Table) modelManager.getModel(rightTable); 25298 if (tableModel != null) { 25299 TableColumn columnModel = modelFactory.createTableColumn(tableModel, 25300 rightObjectName, false); 25301 if(columnModel != null) { 25302 joinRelation.setTarget(new TableColumnRelationshipElement(columnModel)); 25303 } 25304 } 25305 } else if (modelManager.getModel(rightTable) instanceof QueryTable) { 25306 QueryTable table = (QueryTable) modelManager.getModel(rightTable); 25307 TSelectSqlStatement subquery = table.getTableObject().getSubquery(); 25308 if (subquery != null && subquery.isCombinedQuery()) { 25309 ResultColumn resultColumn = matchResultColumn(table.getColumns(), 25310 rightObjectName); 25311 if (resultColumn != null) { 25312 joinRelation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 25313 } 25314 } else if (rightObjectName.getSourceColumn() != null) { 25315 Object model = modelManager.getModel(rightObjectName); 25316 if (model == null) { 25317 model = modelManager 25318 .getModel(rightObjectName.getSourceColumn()); 25319 } 25320 if (model instanceof ResultColumn) { 25321 joinRelation.setTarget(new ResultColumnRelationshipElement((ResultColumn)model)); 25322 } 25323 else if (model instanceof LinkedHashMap) { 25324 String columnName = getColumnNameOnly(rightObjectName.toString()); 25325 LinkedHashMap<String, ResultColumn> resultColumns = (LinkedHashMap<String, ResultColumn>)model; 25326 if (resultColumns.containsKey(columnName)) { 25327 ResultColumn resultColumn = resultColumns.get(columnName); 25328 joinRelation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 25329 } 25330 } 25331 } else { 25332 ResultColumn resultColumn = matchResultColumn(table.getColumns(), 25333 rightObjectName); 25334 if (resultColumn != null) { 25335 joinRelation.setTarget(new ResultColumnRelationshipElement(resultColumn)); 25336 } 25337 } 25338 } 25339 } 25340 else if(rightObject instanceof TFunctionCall) { 25341 Object functionObj = createFunction(rightObject); 25342 if(functionObj instanceof Function) { 25343 Function function = (Function)functionObj; 25344 joinRelation.setTarget(new ResultColumnRelationshipElement(function.getColumns().get(0))); 25345 } 25346 } 25347 } 25348 } 25349 } 25350 } 25351 } 25352 return true; 25353 } 25354 } 25355 25356 @Deprecated 25357 public static Dataflow getSqlflowJSONModel(dataflow dataflow) { 25358 EDbVendor vendor = ModelBindingManager.getGlobalVendor(); 25359 if(vendor == null) { 25360 throw new IllegalArgumentException("getSqlflowJSONModel(dataflow dataflow) is deprecated, please call method getSqlflowJSONModel(dataflow dataflow, EDbVendor vendor)."); 25361 } 25362 return getSqlflowJSONModel(vendor, dataflow, false); 25363 } 25364 25365 public static Dataflow getSqlflowJSONModel(dataflow dataflow, EDbVendor vendor) { 25366 return getSqlflowJSONModel(vendor, dataflow, false); 25367 } 25368 25369 public static Dataflow getSqlflowJSONModel(EDbVendor vendor, dataflow dataflow, boolean normalizeIdentifier) { 25370 Dataflow model = new Dataflow(); 25371 25372 if (dataflow.getErrors() != null && !dataflow.getErrors().isEmpty()) { 25373 List<Error> errorList = new ArrayList<Error>(); 25374 for (error error : dataflow.getErrors()) { 25375 Error err = new Error(); 25376 err.setErrorMessage(error.getErrorMessage()); 25377 err.setErrorType(error.getErrorType()); 25378 err.setCoordinates(Coordinate.parse(error.getCoordinate())); 25379 err.setFile(err.getFile()); 25380 err.setOriginCoordinates(Coordinate.parse(error.getOriginCoordinate())); 25381 errorList.add(err); 25382 } 25383 model.setErrors(errorList.toArray(new Error[0])); 25384 } 25385 25386 Sqlflow sqlflow = MetadataUtil.convertDataflowToMetadata(vendor, dataflow); 25387 sqlflow.setErrorMessages(null); 25388 model.setDbobjs(sqlflow); 25389 model.setOrientation(dataflow.getOrientation()); 25390 25391 25392 List<gudusoft.gsqlparser.dlineage.dataflow.model.json.Process> processes = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.Process>(); 25393 if(dataflow.getProcesses()!=null){ 25394 for(process process: dataflow.getProcesses()){ 25395 gudusoft.gsqlparser.dlineage.dataflow.model.json.Process processModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.Process(); 25396 processModel.setId(process.getId()); 25397 processModel.setName(process.getName()); 25398 processModel.setProcedureId(process.getProcedureId()); 25399 processModel.setProcedureName(process.getProcedureName()); 25400 processModel.setType(process.getType()); 25401 processModel.setCoordinate(process.getCoordinate()); 25402 processModel.setDatabase(process.getDatabase()); 25403 processModel.setSchema(process.getSchema()); 25404 processModel.setServer(process.getServer()); 25405 processModel.setQueryHashId(process.getQueryHashId()); 25406 if (process.getTransforms() != null && !process.getTransforms().isEmpty()) { 25407 List<gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform> transforms = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform>(); 25408 for (transform transform : process.getTransforms()) { 25409 gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform item = new gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform(); 25410 item.setCode(transform.getCode()); 25411 item.setType(transform.getType()); 25412 item.setCoordinate(transform.getCoordinate(true)); 25413 transforms.add(item); 25414 } 25415 processModel.setTransforms(transforms 25416 .toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform[0])); 25417 } 25418 processes.add(processModel); 25419 } 25420 } 25421 model.setProcesses(processes.toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.Process[0])); 25422 25423 List<gudusoft.gsqlparser.dlineage.dataflow.model.json.Relationship> relations = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.Relationship>(); 25424 if (dataflow.getRelationships() != null) { 25425 for (relationship relation : dataflow.getRelationships()) { 25426 gudusoft.gsqlparser.dlineage.dataflow.model.json.Relationship relationModel; 25427 if (relation.getType().equals("join")) { 25428 gudusoft.gsqlparser.dlineage.dataflow.model.json.JoinRelationship joinRelationModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.JoinRelationship(); 25429 joinRelationModel.setCondition(relation.getCondition()); 25430 joinRelationModel.setJoinType(relation.getJoinType()); 25431 joinRelationModel.setClause(relation.getClause()); 25432 relationModel = joinRelationModel; 25433 } else { 25434 relationModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.Relationship(); 25435 } 25436 25437 relationModel.setId(relation.getId()); 25438 relationModel.setProcessId(relation.getProcessId()); 25439 relationModel.setProcessType(relation.getProcessType()); 25440 relationModel.setType(relation.getType()); 25441 relationModel.setEffectType(relation.getEffectType()); 25442 relationModel.setPartition(relation.getPartition()); 25443 relationModel.setFunction(relation.getFunction()); 25444 relationModel.setProcedureId(relation.getProcedureId()); 25445 relationModel.setSqlHash(relation.getSqlHash()); 25446 relationModel.setCondition(relation.getCondition()); 25447 relationModel.setSqlComment(relation.getSqlComment()); 25448 relationModel.setTimestampMax(relation.getTimestampMax()); 25449 relationModel.setTimestampMin(relation.getTimestampMin()); 25450 if (Boolean.TRUE.equals(relation.getBuiltIn())) { 25451 relationModel.setBuiltIn(relation.getBuiltIn()); 25452 } 25453 relationModel.setCallStmt(relation.getCallStmt()); 25454 relationModel.setCallCoordinate(relation.getCallCoordinate()); 25455 25456 if (relation.getTarget() != null && relation.getSources() != null && !relation.getSources().isEmpty()) { 25457 { 25458 gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement targetModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement(); 25459 targetColumn target = relation.getTarget(); 25460 if (normalizeIdentifier) { 25461 targetModel.setColumn(SQLUtil.getIdentifierNormalColumnName(vendor, target.getColumn())); 25462 targetModel.setParentName( 25463 SQLUtil.getIdentifierNormalTableName(vendor, target.getParent_name())); 25464 targetModel.setTargetName( 25465 SQLUtil.getIdentifierNormalColumnName(vendor, target.getTarget_name())); 25466 } else { 25467 targetModel.setColumn(target.getColumn()); 25468 targetModel.setParentName(target.getParent_name()); 25469 targetModel.setTargetName(target.getTarget_name()); 25470 } 25471 targetModel.setId(target.getId()); 25472 targetModel.setTargetId(target.getTarget_id()); 25473 targetModel.setParentId(target.getParent_id()); 25474 targetModel.setCoordinates(Coordinate.parse(target.getCoordinate())); 25475 targetModel.setFunction(target.getFunction()); 25476 targetModel.setType(target.getType()); 25477 relationModel.setTarget(targetModel); 25478 } 25479 25480 List<gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement> sourceModels = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement>(); 25481 for (sourceColumn source : relation.getSources()) { 25482 gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement sourceModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement(); 25483 if (normalizeIdentifier) { 25484 sourceModel.setColumn(SQLUtil.getIdentifierNormalColumnName(vendor, source.getColumn())); 25485 sourceModel.setParentName( 25486 SQLUtil.getIdentifierNormalTableName(vendor, source.getParent_name())); 25487 sourceModel.setSourceName( 25488 SQLUtil.getIdentifierNormalColumnName(vendor, source.getSource_name())); 25489 } else { 25490 sourceModel.setColumn(source.getColumn()); 25491 sourceModel.setParentName(source.getParent_name()); 25492 sourceModel.setSourceName(source.getSource_name()); 25493 } 25494 sourceModel.setColumnType(source.getColumn_type()); 25495 sourceModel.setId(source.getId()); 25496 sourceModel.setParentId(source.getParent_id()); 25497 sourceModel.setSourceId(source.getSource_id()); 25498 sourceModel.setCoordinates(Coordinate.parse(source.getCoordinate())); 25499 sourceModel.setClauseType(source.getClauseType()); 25500 sourceModel.setType(source.getType()); 25501 sourceModels.add(sourceModel); 25502 if (source.getTransforms() != null && !source.getTransforms().isEmpty()) { 25503 List<gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform> transforms = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform>(); 25504 for (transform transform : source.getTransforms()) { 25505 gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform item = new gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform(); 25506 item.setCode(transform.getCode()); 25507 item.setType(transform.getType()); 25508 item.setCoordinate(transform.getCoordinate(true)); 25509 transforms.add(item); 25510 } 25511 sourceModel.setTransforms(transforms 25512 .toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform[0])); 25513 } 25514 25515 if (source.getCandidateParents() != null && !source.getCandidateParents().isEmpty()) { 25516 List<gudusoft.gsqlparser.dlineage.dataflow.model.json.CandidateTable> candidateParents = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.CandidateTable>(); 25517 for (candidateTable candidateTable : source.getCandidateParents()) { 25518 gudusoft.gsqlparser.dlineage.dataflow.model.json.CandidateTable item = new gudusoft.gsqlparser.dlineage.dataflow.model.json.CandidateTable(); 25519 item.setId(candidateTable.getId()); 25520 if (normalizeIdentifier) { 25521 item.setName( 25522 SQLUtil.getIdentifierNormalTableName(vendor, candidateTable.getName())); 25523 } else { 25524 item.setName(candidateTable.getName()); 25525 } 25526 candidateParents.add(item); 25527 } 25528 sourceModel.setCandidateParents(candidateParents 25529 .toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.CandidateTable[0])); 25530 } 25531 } 25532 relationModel.setSources(sourceModels 25533 .toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement[0])); 25534 relations.add(relationModel); 25535 } else if (relation.getCaller() != null && relation.getCallees() != null 25536 && !relation.getCallees().isEmpty()) { 25537 { 25538 gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement targetModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement(); 25539 targetColumn target = relation.getCaller(); 25540 if (normalizeIdentifier) { 25541 targetModel.setName(SQLUtil.getIdentifierNormalColumnName(vendor, target.getName())); 25542 } else { 25543 targetModel.setName(target.getName()); 25544 } 25545 targetModel.setId(target.getId()); 25546 targetModel.setCoordinates(Coordinate.parse(target.getCoordinate())); 25547 targetModel.setType(target.getType()); 25548 relationModel.setCaller(targetModel); 25549 } 25550 25551 List<gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement> sourceModels = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement>(); 25552 for (sourceColumn source : relation.getCallees()) { 25553 gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement sourceModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement(); 25554 if (normalizeIdentifier) { 25555 sourceModel.setName(SQLUtil.getIdentifierNormalColumnName(vendor, source.getName())); 25556 } else { 25557 sourceModel.setName(source.getName()); 25558 } 25559 sourceModel.setId(source.getId()); 25560 sourceModel.setCoordinates(Coordinate.parse(source.getCoordinate())); 25561 sourceModel.setType(source.getType()); 25562 sourceModels.add(sourceModel); 25563 } 25564 relationModel.setCallees(sourceModels 25565 .toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement[0])); 25566 relations.add(relationModel); 25567 } 25568 } 25569 } 25570 model.setRelationships(relations.toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.Relationship[0])); 25571 return model; 25572 } 25573 25574 public static String getVersion() { 25575 return "3.1.4"; 25576 } 25577 25578 public static String getReleaseDate() { 25579 return "2023-03-04"; 25580 } 25581 25582 public static void main(String[] args) { 25583 if (args.length < 1) { 25584 System.out.println( 25585 "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]"); 25586 System.out.println("/f: Option, specify the sql file path to analyze fdd relation."); 25587 System.out.println("/d: Option, specify the sql directory path to analyze fdd relation."); 25588 System.out.println("/j: Option, analyze the join relation."); 25589 System.out.println("/s: Option, simple output, ignore the intermediate results."); 25590 System.out.println("/i: Option, ignore all result sets."); 25591 System.out.println("/traceView: Option, analyze the source tables of views."); 25592 System.out.println("/text: Option, print the plain text format output."); 25593 System.out.println("/json: Option, print the json format output."); 25594 System.out.println( 25595 "/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"); 25596 System.out.println("/o: Option, write the output stream to the specified file."); 25597 System.out.println("/log: Option, generate a dataflow.log file to log information."); 25598 return; 25599 } 25600 25601 File sqlFiles = null; 25602 25603 List<String> argList = Arrays.asList(args); 25604 25605 if (argList.indexOf("/version") != -1) { 25606 System.out.println("Version: " + DataFlowAnalyzer.getVersion()); 25607 System.out.println("Release Date: " + DataFlowAnalyzer.getReleaseDate()); 25608 return; 25609 } 25610 25611 if (argList.indexOf("/f") != -1 && argList.size() > argList.indexOf("/f") + 1) { 25612 sqlFiles = new File(args[argList.indexOf("/f") + 1]); 25613 if (!sqlFiles.exists() || !sqlFiles.isFile()) { 25614 System.out.println(sqlFiles + " is not a valid file."); 25615 return; 25616 } 25617 } else if (argList.indexOf("/d") != -1 && argList.size() > argList.indexOf("/d") + 1) { 25618 sqlFiles = new File(args[argList.indexOf("/d") + 1]); 25619 if (!sqlFiles.exists() || !sqlFiles.isDirectory()) { 25620 System.out.println(sqlFiles + " is not a valid directory."); 25621 return; 25622 } 25623 } else { 25624 System.out.println("Please specify a sql file path or directory path to analyze dlineage."); 25625 return; 25626 } 25627 25628 EDbVendor vendor = EDbVendor.dbvoracle; 25629 25630 int index = argList.indexOf("/t"); 25631 25632 if (index != -1 && args.length > index + 1) { 25633 vendor = TGSqlParser.getDBVendorByName(args[index + 1]); 25634 } 25635 25636 String outputFile = null; 25637 25638 index = argList.indexOf("/o"); 25639 25640 if (index != -1 && args.length > index + 1) { 25641 outputFile = args[index + 1]; 25642 } 25643 25644 FileOutputStream writer = null; 25645 if (outputFile != null) { 25646 try { 25647 writer = new FileOutputStream(outputFile); 25648 System.setOut(new PrintStream(writer)); 25649 } catch (FileNotFoundException e) { 25650 logger.error("output file is not found.", e); 25651 } 25652 } 25653 25654 boolean simple = argList.indexOf("/s") != -1; 25655 boolean ignoreResultSets = argList.indexOf("/i") != -1; 25656 boolean showJoin = argList.indexOf("/j") != -1; 25657 boolean textFormat = false; 25658 boolean jsonFormat = false; 25659 if (simple) { 25660 textFormat = argList.indexOf("/text") != -1; 25661 } 25662 25663 boolean traceView = argList.indexOf("/traceView") != -1; 25664 if (traceView) { 25665 simple = true; 25666 } 25667 25668 jsonFormat = argList.indexOf("/json") != -1; 25669 25670 DataFlowAnalyzer dlineage = new DataFlowAnalyzer(sqlFiles, vendor, simple); 25671 25672 dlineage.setShowJoin(showJoin); 25673 dlineage.setIgnoreRecordSet(ignoreResultSets); 25674 // dlineage.setShowImplicitSchema(true); 25675 25676 if (simple && !jsonFormat) { 25677 dlineage.setTextFormat(textFormat); 25678 } 25679 25680 String result = dlineage.generateDataFlow(); 25681 25682// dataflow dataflow = ProcessUtility.generateTableLevelLineage(dlineage, dlineage.getDataFlow()); 25683// System.out.println(result); 25684 25685 if (jsonFormat) { 25686 // Map jsonResult = new LinkedHashMap(); 25687 Dataflow model = getSqlflowJSONModel(vendor, dlineage.getDataFlow(), true); 25688 // jsonResult.put("data", BeanUtils.bean2Map(model)); 25689 result = JSON.toJSONString(model); 25690 } else if (traceView) { 25691 result = dlineage.traceView(); 25692 } 25693 25694 if (result != null) { 25695 System.out.println(result); 25696 25697 if (writer != null && result.length() < 1024 * 1024) { 25698 System.err.println(result); 25699 } 25700 } 25701 25702 try { 25703 if (writer != null) { 25704 writer.close(); 25705 } 25706 } catch (IOException e) { 25707 logger.error("close writer failed.", e); 25708 } 25709 25710 boolean log = argList.indexOf("/log") != -1; 25711 25712 PrintStream systemSteam = System.err; 25713 ByteArrayOutputStream sw = new ByteArrayOutputStream(); 25714 PrintStream pw = new PrintStream(sw); 25715 System.setErr(pw); 25716 25717 25718 List<ErrorInfo> errors = dlineage.getErrorMessages(); 25719 if (!errors.isEmpty()) { 25720 System.err.println("Error log:\n"); 25721 for (int i = 0; i < errors.size(); i++) { 25722 System.err.println(errors.get(i).getErrorMessage()); 25723 } 25724 } 25725 25726 if (sw != null) { 25727 String errorMessage = sw.toString().trim(); 25728 if (errorMessage.length() > 0) { 25729 if (log) { 25730 try { 25731 pw = new PrintStream(new File(".", "dataflow.log")); 25732 pw.print(errorMessage); 25733 } catch (FileNotFoundException e) { 25734 logger.error("error log file is not found.", e); 25735 } 25736 } 25737 25738 System.setErr(systemSteam); 25739 System.err.println(errorMessage); 25740 } 25741 } 25742 } 25743 25744 public List<ErrorInfo> getErrorMessages() { 25745 return errorInfos; 25746 } 25747 25748 /** 25749 * Every dynamic-SQL execution site (T-SQL {@code EXEC(...)} / {@code sp_executesql}) the analyzer 25750 * encountered, with whether it was statically resolved. Diagnostic only; not consumed by lineage. 25751 * Read-only snapshot; see {@link DynamicSqlSite}. 25752 */ 25753 public List<DynamicSqlSite> getDynamicSqlSites() { 25754 return java.util.Collections.unmodifiableList(new ArrayList<DynamicSqlSite>(dynamicSqlSites)); 25755 } 25756 25757 /** 25758 * Resolve dynamic-SQL object names by abstractly evaluating a stored procedure 25759 * with a set of parameter bindings. 25760 * 25761 * <p>Given a T-SQL {@code CREATE PROC} parse tree and the values its parameters 25762 * actually had at a call site (e.g. {@code @SourceDB='QSP'}, 25763 * {@code @STG_AEG='STG_AEG'}), this evaluates the procedure's dynamic-SQL string 25764 * building (assignment + concatenation + name-building functions), materializes 25765 * the concrete SQL each {@code EXEC} / {@code sp_executesql} site runs, analyzes 25766 * it with ordinary dlineage, and returns the lineage edges tagged with dynamic 25767 * provenance ({@code origin=DYNAMIC_RESOLVED}, source proc, stable dynamic-site 25768 * id, binding hash). Sites that cannot be reduced are reported as honest 25769 * {@code UNRESOLVED} diagnostics — never guessed. 25770 * 25771 * <p>This is abstract string evaluation, NOT execution: no table reads, no 25772 * cursors, no data-dependent control flow. It is purely additive — it builds 25773 * throwaway analyzers for the materialized strings and does not change the 25774 * default dlineage output of this analyzer. 25775 * 25776 * @param procAst the {@code CREATE PROC} parse tree (currently T-SQL) 25777 * @param vendor the SQL dialect ({@code dbvmssql}) 25778 * @param sqlEnv catalog env for the resolved analysis (may be null) 25779 * @param currentDatabase the proc's database (resolves unqualified names) 25780 * @param defaultSchema the proc's default schema (e.g. {@code dbo}) 25781 * @param bindings parameter name → concrete value 25782 * @param options resource bounds (may be null for defaults) 25783 */ 25784 public gudusoft.gsqlparser.dlineage.dynamicsql.DynamicLineageResult resolveDynamicSqlLineage( 25785 TCustomSqlStatement procAst, EDbVendor vendor, gudusoft.gsqlparser.sqlenv.TSQLEnv sqlEnv, 25786 String currentDatabase, String defaultSchema, 25787 Map<String, gudusoft.gsqlparser.dlineage.dynamicsql.SqlValue> bindings, 25788 gudusoft.gsqlparser.dlineage.dynamicsql.DynamicLineageOptions options) { 25789 return gudusoft.gsqlparser.dlineage.dynamicsql.DynamicSqlLineageResolver.resolve( 25790 procAst, vendor, sqlEnv, currentDatabase, defaultSchema, bindings, options); 25791 } 25792 25793 public String traceView() { 25794 StringBuilder buffer = new StringBuilder(); 25795 dataflow dataflow = this.getDataFlow(); 25796 Map<table, Set<table>> traceViewMap = new LinkedHashMap<table, Set<table>>(); 25797 if (dataflow != null && dataflow.getViews() != null) { 25798 List<relationship> relations = dataflow.getRelationships(); 25799 Map<String, table> viewMap = new HashMap<String, table>(); 25800 Map<String, table> tableMap = new HashMap<String, table>(); 25801 for (table view : dataflow.getViews()) { 25802 viewMap.put(view.getId(), view); 25803 tableMap.put(view.getId(), view); 25804 } 25805 for (table table : dataflow.getTables()) { 25806 tableMap.put(table.getId(), table); 25807 } 25808 for (relationship relation : relations) { 25809 if (!RelationshipType.fdd.name().equals(relation.getType())) { 25810 continue; 25811 } 25812 String parentId = relation.getTarget().getParent_id(); 25813 if (viewMap.containsKey(parentId)) { 25814 if (!traceViewMap.containsKey(viewMap.get(parentId))) { 25815 traceViewMap.put(viewMap.get(parentId), new LinkedHashSet<table>()); 25816 } 25817 25818 for (sourceColumn sourceColumn : relation.getSources()) { 25819 traceViewMap.get(viewMap.get(parentId)).add(tableMap.get(sourceColumn.getParent_id())); 25820 } 25821 } 25822 } 25823 25824 Map<table, Set<table>> viewTableMap = new LinkedHashMap<table, Set<table>>(); 25825 for (table view : traceViewMap.keySet()) { 25826 Set<table> tables = new LinkedHashSet<table>(); 25827 traverseViewSourceTables(tables, view, traceViewMap); 25828 viewTableMap.put(view, tables); 25829 } 25830 25831 for (table view : viewTableMap.keySet()) { 25832 buffer.append(view.getFullName()); 25833 for (table table : viewTableMap.get(view)) { 25834 buffer.append(",").append(table.getFullName()); 25835 } 25836 buffer.append(System.getProperty("line.separator")); 25837 } 25838 } 25839 return buffer.toString().trim(); 25840 } 25841 25842 private void traverseViewSourceTables(Set<table> tables, table view, Map<table, Set<table>> traceViewMap) { 25843 Set<table> sourceTables = traceViewMap.get(view); 25844 for (table sourceTable : sourceTables) { 25845 if (sourceTable.isTable()) { 25846 tables.add(sourceTable); 25847 } else if (sourceTable.isView()) { 25848 traverseViewSourceTables(tables, sourceTable, traceViewMap); 25849 } 25850 } 25851 } 25852 25853 protected List<SqlInfo> convertSQL(EDbVendor vendor, String json) { 25854 List<SqlInfo> sqlInfos = new ArrayList<SqlInfo>(); 25855 List sqlContents = (List) JSON.parseObject(json); 25856 for (int j = 0; j < sqlContents.size(); j++) { 25857 Map sqlContent = (Map) sqlContents.get(j); 25858 String sql = (String) sqlContent.get("sql"); 25859 String fileName = (String) sqlContent.get("fileName"); 25860 String filePath = (String) sqlContent.get("filePath"); 25861 if (sql != null && sql.trim().startsWith("{")) { 25862 if (sql.indexOf("createdBy") != -1) { 25863 if (this.sqlenv == null) { 25864 TSQLEnv[] sqlenvs = new TJSONSQLEnvParser(option.getDefaultServer(), 25865 option.getDefaultDatabase(), option.getDefaultSchema()).parseSQLEnv(vendor, sql); 25866 if (sqlenvs != null && sqlenvs.length > 0) { 25867 this.sqlenv = sqlenvs[0]; 25868 } 25869 } 25870 if (sql.toLowerCase().indexOf("sqldep") != -1 || sql.toLowerCase().indexOf("grabit") != -1) { 25871 Map queryObject = (Map) JSON.parseObject(sql); 25872 List querys = (List) queryObject.get("queries"); 25873 if (querys != null) { 25874 for (int i = 0; i < querys.size(); i++) { 25875 Map object = (Map) querys.get(i); 25876 SqlInfo info = new SqlInfo(); 25877 info.setSql(JSON.toJSONString(object)); 25878 info.setFileName(fileName); 25879 info.setFilePath(filePath); 25880 info.setOriginIndex(i); 25881 sqlInfos.add(info); 25882 } 25883 queryObject.remove("queries"); 25884 SqlInfo info = new SqlInfo(); 25885 info.setSql(JSON.toJSONString(queryObject)); 25886 info.setFileName(fileName); 25887 info.setFilePath(filePath); 25888 info.setOriginIndex(querys.size()); 25889 sqlInfos.add(info); 25890 } else { 25891 SqlInfo info = new SqlInfo(); 25892 info.setSql(JSON.toJSONString(queryObject)); 25893 info.setFileName(fileName); 25894 info.setFilePath(filePath); 25895 info.setOriginIndex(0); 25896 sqlInfos.add(info); 25897 } 25898 } else if (sql.toLowerCase().indexOf("sqlflow") != -1) { 25899 Map sqlflow = (Map) JSON.parseObject(sql); 25900 List<Map> servers = (List<Map>) sqlflow.get("servers"); 25901 if (servers != null) { 25902 for (Map queryObject : servers) { 25903 String name = (String) queryObject.get("name"); 25904 String dbVendor = (String) queryObject.get("dbVendor"); 25905 List querys = (List) queryObject.get("queries"); 25906 if (querys != null) { 25907 for (int i = 0; i < querys.size(); i++) { 25908 Map object = (Map) querys.get(i); 25909 SqlInfo info = new SqlInfo(); 25910 info.setSql(JSON.toJSONString(object)); 25911 info.setFileName(fileName); 25912 info.setFilePath(filePath); 25913 info.setOriginIndex(i); 25914 info.setDbVendor(dbVendor); 25915 info.setServer(name); 25916 sqlInfos.add(info); 25917 } 25918 queryObject.remove("queries"); 25919 Map serverObject = new IndexedLinkedHashMap(); 25920 serverObject.put("createdBy", sqlflow.get("createdBy")); 25921 serverObject.put("servers", Arrays.asList(queryObject)); 25922 SqlInfo info = new SqlInfo(); 25923 info.setSql(JSON.toJSONString(serverObject)); 25924 info.setFileName(fileName); 25925 info.setFilePath(filePath); 25926 info.setOriginIndex(querys.size()); 25927 info.setDbVendor(dbVendor); 25928 info.setServer(filePath); 25929 sqlInfos.add(info); 25930 } else { 25931 SqlInfo info = new SqlInfo(); 25932 info.setSql(JSON.toJSONString(queryObject)); 25933 info.setFileName(fileName); 25934 info.setFilePath(filePath); 25935 info.setOriginIndex(0); 25936 sqlInfos.add(info); 25937 } 25938 } 25939 } 25940 25941 List<Map> errorMessages = (List<Map>) sqlflow.get("errorMessages"); 25942 if(errorMessages!=null && !errorMessages.isEmpty()) { 25943 for(Map error: errorMessages){ 25944 ErrorInfo errorInfo = new ErrorInfo(); 25945 errorInfo.setErrorType(ErrorInfo.METADATA_ERROR); 25946 errorInfo.setErrorMessage((String)error.get("errorMessage")); 25947 errorInfo.setFileName(fileName); 25948 errorInfo.setFilePath(filePath); 25949 errorInfo.setStartPosition(new Pair3<Long, Long, String>(-1L, -1L, 25950 ModelBindingManager.getGlobalHash())); 25951 errorInfo.setEndPosition(new Pair3<Long, Long, String>(-1L, -1L, 25952 ModelBindingManager.getGlobalHash())); 25953 errorInfo.setOriginStartPosition(new Pair<Long, Long>(-1L, -1L)); 25954 errorInfo.setOriginEndPosition(new Pair<Long, Long>(-1L, -1L)); 25955 metadataErrors.add(errorInfo); 25956 } 25957 } 25958 } 25959 } 25960 } else if (sql != null) { 25961 SqlInfo info = new SqlInfo(); 25962 info.setSql(sql); 25963 info.setFileName(fileName); 25964 info.setFilePath(filePath); 25965 info.setOriginIndex(0); 25966 sqlInfos.add(info); 25967 } 25968 } 25969 return sqlInfos; 25970 } 25971 25972 public void setTextFormat(boolean textFormat) { 25973 option.setTextFormat(textFormat); 25974 } 25975 25976 public boolean isBuiltInFunctionName(TObjectName object) { 25977 if (object == null || object.getGsqlparser() == null) 25978 return false; 25979 try { 25980 EDbVendor vendor = object.getGsqlparser().getDbVendor(); 25981 if (vendor == EDbVendor.dbvteradata) { 25982 boolean result = TERADATA_BUILTIN_FUNCTIONS.contains(object.toString().toUpperCase()); 25983 if (result) { 25984 return true; 25985 } 25986 } 25987 25988 List<String> versions = functionChecker.getAvailableDbVersions(vendor); 25989 if (versions != null && versions.size() > 0) { 25990 for (int i = 0; i < versions.size(); i++) { 25991 boolean result = functionChecker.isBuiltInFunction(object.toString(), 25992 object.getGsqlparser().getDbVendor(), versions.get(i)); 25993 if (result) { 25994 return result; 25995 } 25996 } 25997 25998 // boolean result = 25999 // TERADATA_BUILTIN_FUNCTIONS.contains(object.toString()); 26000 // if (result) { 26001 // return true; 26002 // } 26003 } 26004 } catch (Exception e) { 26005 } 26006 26007 return false; 26008 } 26009 26010 public boolean isBuiltInFunctionName(String functionName) { 26011 if (functionName == null) 26012 return false; 26013 try { 26014 EDbVendor vendor = getOption().getVendor(); 26015 if (vendor == EDbVendor.dbvteradata) { 26016 boolean result = TERADATA_BUILTIN_FUNCTIONS.contains(functionName.toUpperCase()); 26017 if (result) { 26018 return true; 26019 } 26020 } 26021 26022 List<String> versions = functionChecker.getAvailableDbVersions(vendor); 26023 if (versions != null && versions.size() > 0) { 26024 for (int i = 0; i < versions.size(); i++) { 26025 boolean result = functionChecker.isBuiltInFunction(functionName.toUpperCase(), 26026 vendor, versions.get(i)); 26027 if (result) { 26028 return result; 26029 } 26030 } 26031 26032 // boolean result = 26033 // TERADATA_BUILTIN_FUNCTIONS.contains(object.toString()); 26034 // if (result) { 26035 // return true; 26036 // } 26037 } 26038 } catch (Exception e) { 26039 } 26040 26041 return false; 26042 } 26043 26044 public boolean isKeyword(TObjectName object) { 26045 if (object == null || object.getGsqlparser() == null) 26046 return false; 26047 try { 26048 EDbVendor vendor = object.getGsqlparser().getDbVendor(); 26049 26050 List<String> versions = keywordChecker.getAvailableDbVersions(vendor); 26051 if (versions != null && versions.size() > 0) { 26052 for (int i = 0; i < versions.size(); i++) { 26053 List<String> segments = SQLUtil.parseNames(object.toString()); 26054 boolean result = keywordChecker.isKeyword(segments.get(segments.size() - 1), 26055 object.getGsqlparser().getDbVendor(), versions.get(i), true); 26056 if (result) { 26057 return result; 26058 } 26059 } 26060 } 26061 } catch (Exception e) { 26062 } 26063 26064 return false; 26065 } 26066 26067 public boolean isKeyword(String objectName) { 26068 if (objectName == null) 26069 return false; 26070 try { 26071 EDbVendor vendor = getOption().getVendor(); 26072 26073 List<String> versions = keywordChecker.getAvailableDbVersions(vendor); 26074 if (versions != null && versions.size() > 0) { 26075 for (int i = 0; i < versions.size(); i++) { 26076 List<String> segments = SQLUtil.parseNames(objectName); 26077 boolean result = keywordChecker.isKeyword(segments.get(segments.size() - 1), 26078 vendor, versions.get(i), false); 26079 if (result) { 26080 return result; 26081 } 26082 } 26083 } 26084 } catch (Exception e) { 26085 } 26086 26087 return false; 26088 } 26089 26090 public boolean isAggregateFunction(TFunctionCall func) { 26091 if (func == null) 26092 return false; 26093 return Arrays 26094 .asList(new String[] { "AVG", "COUNT", "MAX", "MIN", "SUM", "COLLECT", "CORR", "COVAR_POP", 26095 "COVAR_SAMP", "CUME_DIST", "DENSE_RANK", "FIRST", "GROUP_ID", "GROUPING", "GROUPING_ID", "LAST", 26096 "LISTAGG", "MEDIAN", "PERCENT_RANK", "PERCENTILE_CONT", "PERCENTILE_DISC", "RANK", 26097 "STATS_BINOMIAL_TEST", "STATS_CROSSTAB", "STATS_F_TEST", "STATS_KS_TEST", "STATS_MODE", 26098 "STATS_MW_TEST", "STATS_ONE_WAY_ANOVA", "STATS_WSR_TEST", "STDDEV", "STDDEV_POP", "STDDEV_SAMP", 26099 "SYS_XMLAGG", "VAR_ POP", "VAR_ SAMP", "VARI ANCE", "XMLAGG", "ARRAY_AGG" }) 26100 .contains(func.getFunctionName().toString().toUpperCase()); 26101 } 26102 26103 public boolean isConstant(TObjectName object) { 26104 if (object == null || object.getGsqlparser() == null) 26105 return false; 26106 List<String> constants = Arrays.asList(new String[] { "NEXTVAL", "CURRVAL", "SYSDATE", "CENTURY", "YEAR", 26107 "MONTH", "DAY", "HOUR", "MINUTE", "SECOND" }); 26108 List<String> segments = SQLUtil.parseNames(object.toString()); 26109 // sequence.NEXTVAL or sequence.CURRVAL is a sequence reference, not a constant 26110 // This syntax is used by Oracle, Snowflake, and accepted by other vendors for compatibility 26111 String columnNameOnly = object.getColumnNameOnly(); 26112 if (segments.size() > 1 && ("NEXTVAL".equalsIgnoreCase(columnNameOnly) || "CURRVAL".equalsIgnoreCase(columnNameOnly))) { 26113 return false; 26114 } 26115 boolean result = constants.indexOf(segments.get(segments.size() - 1).toUpperCase()) != -1; 26116 if (result) { 26117 return result; 26118 } 26119 if (isKeyword(object)) { 26120 return true; 26121 } 26122 return false; 26123 } 26124 26125 private Pair3<Long, Long, Integer> convertCoordinate(Pair3<Long, Long, String> position) { 26126// if (ModelBindingManager.getGlobalOption()!=null && ModelBindingManager.getGlobalOption().isIgnoreCoordinate()) { 26127// return new Pair3<>(-1L, -1L, -1); 26128// } 26129 return new Pair3<Long, Long, Integer>(position.first, position.second, 26130 ModelBindingManager.getGlobalSqlInfo().getIndexOf(position.third)); 26131 } 26132 26133 /** 26134 * Analyze MDX SELECT statement to generate data lineage. 26135 * Maps MDX cube as source table, measures/dimensions as columns, 26136 * and creates dataflow relationships to the result set. 26137 */ 26138 private void analyzeMdxSelectStmt(gudusoft.gsqlparser.stmt.mdx.TMdxSelect stmt) { 26139 // Get cube name from FROM clause 26140 gudusoft.gsqlparser.nodes.mdx.TMdxIdentifierNode cube = stmt.getCube(); 26141 if (cube == null) { 26142 return; 26143 } 26144 26145 String cubeName = getMdxIdentifierName(cube); 26146 Table cubeTable = modelFactory.createTableByName(cubeName, false); 26147 26148 // Collect all MDX identifier references from axes and WHERE clause 26149 List<String> measureNames = new ArrayList<String>(); 26150 List<String> dimensionNames = new ArrayList<String>(); 26151 26152 // Process axes (COLUMNS, ROWS, etc.) 26153 if (stmt.getAxes() != null) { 26154 for (int i = 0; i < stmt.getAxes().size(); i++) { 26155 gudusoft.gsqlparser.nodes.mdx.TMdxAxisNode axis = stmt.getAxes().getElement(i); 26156 if (axis.getExpNode() != null) { 26157 collectMdxReferences(axis.getExpNode(), measureNames, dimensionNames); 26158 } 26159 } 26160 } 26161 26162 // Process WHERE clause (slicer dimension) 26163 if (stmt.getWhere() != null && stmt.getWhere().getFilter() != null) { 26164 collectMdxReferences(stmt.getWhere().getFilter(), measureNames, dimensionNames); 26165 } 26166 26167 // Process WITH MEMBER definitions 26168 if (stmt.getWiths() != null) { 26169 for (int i = 0; i < stmt.getWiths().size(); i++) { 26170 gudusoft.gsqlparser.nodes.mdx.TMdxWithNode withNode = stmt.getWiths().getElement(i); 26171 if (withNode.getNameNode() != null) { 26172 String withName = getMdxIdentifierName(withNode.getNameNode()); 26173 // Calculated members are treated as derived measures 26174 if (withName.toLowerCase().startsWith("[measures].") 26175 || withName.toLowerCase().startsWith("measures.")) { 26176 measureNames.add(withName); 26177 } 26178 } 26179 // Also collect references used in the WITH expression 26180 if (withNode.getExprNode() != null) { 26181 collectMdxReferences(withNode.getExprNode(), measureNames, dimensionNames); 26182 } 26183 } 26184 } 26185 26186 // Create columns on the cube table for all referenced measures and dimensions 26187 Set<String> addedColumns = new LinkedHashSet<String>(); 26188 for (String measure : measureNames) { 26189 if (addedColumns.add(measure)) { 26190 modelFactory.createTableColumn(cubeTable, measure); 26191 } 26192 } 26193 for (String dimension : dimensionNames) { 26194 if (addedColumns.add(dimension)) { 26195 modelFactory.createTableColumn(cubeTable, dimension); 26196 } 26197 } 26198 26199 // Create result set with all referenced columns 26200 ResultSet resultSet = modelFactory.createResultSet(stmt, false); 26201 if (resultSet != null) { 26202 for (String colName : addedColumns) { 26203 TableColumn sourceCol = findTableColumnByName(cubeTable, colName); 26204 if (sourceCol != null) { 26205 DataFlowRelationship relation = modelFactory.createDataFlowRelation(); 26206 relation.setEffectType(EffectType.select); 26207 relation.addSource(new TableColumnRelationshipElement(sourceCol)); 26208 relation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>( 26209 resultSet.getRelationRows())); 26210 } 26211 } 26212 } 26213 } 26214 26215 private TableColumn findTableColumnByName(Table table, String name) { 26216 for (TableColumn col : table.getColumns()) { 26217 if (col.getName().equals(name)) { 26218 return col; 26219 } 26220 } 26221 return null; 26222 } 26223 26224 /** 26225 * Extract the display name from an MDX identifier node. 26226 * E.g., [Measures].[Departures NEAT] -> [Measures].[Departures NEAT] 26227 */ 26228 private String getMdxIdentifierName(gudusoft.gsqlparser.nodes.mdx.TMdxIdentifierNode idNode) { 26229 StringBuilder sb = new StringBuilder(); 26230 for (int i = 0; i < idNode.getSegmentList().size(); i++) { 26231 if (i > 0) sb.append("."); 26232 gudusoft.gsqlparser.nodes.mdx.IMdxIdentifierSegment seg = idNode.getSegmentList().getElement(i); 26233 if (seg.getQuoting() == gudusoft.gsqlparser.nodes.mdx.EMdxQuoting.QUOTED) { 26234 sb.append("[").append(seg.getName()).append("]"); 26235 } else { 26236 sb.append(seg.getName()); 26237 } 26238 } 26239 return sb.toString(); 26240 } 26241 26242 /** 26243 * Recursively collect measure and dimension references from MDX expression tree. 26244 * Uses iterative DFS to avoid StackOverflow on deeply nested expressions. 26245 */ 26246 private void collectMdxReferences(gudusoft.gsqlparser.nodes.mdx.TMdxExpNode expr, 26247 List<String> measures, List<String> dimensions) { 26248 Deque<gudusoft.gsqlparser.nodes.mdx.TMdxExpNode> stack = new ArrayDeque<gudusoft.gsqlparser.nodes.mdx.TMdxExpNode>(); 26249 stack.push(expr); 26250 26251 while (!stack.isEmpty()) { 26252 gudusoft.gsqlparser.nodes.mdx.TMdxExpNode current = stack.pop(); 26253 if (current == null) continue; 26254 26255 if (current instanceof gudusoft.gsqlparser.nodes.mdx.TMdxIdentifierNode) { 26256 gudusoft.gsqlparser.nodes.mdx.TMdxIdentifierNode idNode = 26257 (gudusoft.gsqlparser.nodes.mdx.TMdxIdentifierNode) current; 26258 String name = getMdxIdentifierName(idNode); 26259 if (name.toLowerCase().startsWith("[measures].") 26260 || name.toLowerCase().startsWith("measures.")) { 26261 measures.add(name); 26262 } else if (idNode.getSegmentList().size() > 1) { 26263 // Multi-segment identifiers that aren't measures are dimensions 26264 dimensions.add(name); 26265 } 26266 } else if (current instanceof gudusoft.gsqlparser.nodes.mdx.TMdxSetNode) { 26267 gudusoft.gsqlparser.nodes.mdx.TMdxSetNode setNode = 26268 (gudusoft.gsqlparser.nodes.mdx.TMdxSetNode) current; 26269 if (setNode.getTupleList() != null) { 26270 for (int i = 0; i < setNode.getTupleList().size(); i++) { 26271 stack.push(setNode.getTupleList().getElement(i)); 26272 } 26273 } 26274 } else if (current instanceof gudusoft.gsqlparser.nodes.mdx.TMdxTupleNode) { 26275 gudusoft.gsqlparser.nodes.mdx.TMdxTupleNode tupleNode = 26276 (gudusoft.gsqlparser.nodes.mdx.TMdxTupleNode) current; 26277 if (tupleNode.getExprList() != null) { 26278 for (int i = 0; i < tupleNode.getExprList().size(); i++) { 26279 stack.push(tupleNode.getExprList().getElement(i)); 26280 } 26281 } 26282 } else if (current instanceof gudusoft.gsqlparser.nodes.mdx.TMdxBinOpNode) { 26283 gudusoft.gsqlparser.nodes.mdx.TMdxBinOpNode binOp = 26284 (gudusoft.gsqlparser.nodes.mdx.TMdxBinOpNode) current; 26285 if (binOp.getRightExprNode() != null) stack.push(binOp.getRightExprNode()); 26286 if (binOp.getLeftExprNode() != null) stack.push(binOp.getLeftExprNode()); 26287 } else if (current instanceof gudusoft.gsqlparser.nodes.mdx.TMdxFunctionNode) { 26288 gudusoft.gsqlparser.nodes.mdx.TMdxFunctionNode funcNode = 26289 (gudusoft.gsqlparser.nodes.mdx.TMdxFunctionNode) current; 26290 if (funcNode.getArguments() != null) { 26291 for (int i = 0; i < funcNode.getArguments().size(); i++) { 26292 stack.push(funcNode.getArguments().getElement(i)); 26293 } 26294 } 26295 } 26296 } 26297 } 26298 26299 /** 26300 * Analyze a Power Query M-language document for data lineage. 26301 * 26302 * Delegates to TPowerQueryAnalyzer to extract navigation chains and 26303 * NativeQuery embedded SQL, then feeds the results back through the 26304 * standard SQL analysis pipeline so the dataflow model contains 26305 * regular table/column lineage. 26306 */ 26307 private void analyzePowerQueryDocumentStmt(TPowerQueryDocumentStmt pqStmt) { 26308 TPowerQueryAnalyzer pqAnalyzer = new TPowerQueryAnalyzer(pqStmt); 26309 26310 if (option.getPowerQueryInnerVendor() != null) { 26311 pqAnalyzer.withExplicitInnerVendor(option.getPowerQueryInnerVendor()); 26312 } 26313 26314 PowerQueryLineageResult result = pqAnalyzer.analyze(); 26315 26316 if (result.isEmpty()) { 26317 for (String w : result.getWarnings()) { 26318 logger.warn("Power Query: " + w); 26319 } 26320 return; 26321 } 26322 26323 for (PowerQueryLineageResult.NativeQueryRef nq : result.getNativeQueryReferences()) { 26324 if (nq.innerParser != null && nq.innerParseReturnCode == 0) { 26325 for (int i = 0; i < nq.innerParser.sqlstatements.size(); i++) { 26326 analyzeCustomSqlStmt(nq.innerParser.sqlstatements.get(i)); 26327 } 26328 } 26329 } 26330 26331 for (PowerQueryLineageResult.NavigationRef nav : result.getNavigationReferences()) { 26332 if (nav.syntheticSelect != null && nav.resolvedVendor != null) { 26333 TGSqlParser synParser = new TGSqlParser(nav.resolvedVendor); 26334 synParser.sqltext = nav.syntheticSelect; 26335 int rc = synParser.parse(); 26336 if (rc == 0) { 26337 for (int i = 0; i < synParser.sqlstatements.size(); i++) { 26338 analyzeCustomSqlStmt(synParser.sqlstatements.get(i)); 26339 } 26340 } 26341 } 26342 } 26343 26344 for (String w : result.getWarnings()) { 26345 logger.warn("Power Query: " + w); 26346 } 26347 } 26348 26349}