001 002package gudusoft.gsqlparser.dlineage.dataflow.model; 003 004import gudusoft.gsqlparser.EDbVendor; 005import gudusoft.gsqlparser.EExpressionType; 006import gudusoft.gsqlparser.ESetOperatorType; 007import gudusoft.gsqlparser.TCustomSqlStatement; 008import gudusoft.gsqlparser.dlineage.util.DlineageUtil; 009import gudusoft.gsqlparser.dlineage.util.Pair; 010import gudusoft.gsqlparser.dlineage.util.Pair3; 011import gudusoft.gsqlparser.dlineage.util.SHA256; 012import gudusoft.gsqlparser.nodes.*; 013import gudusoft.gsqlparser.sqlenv.TSQLEnv; 014import gudusoft.gsqlparser.stmt.*; 015import gudusoft.gsqlparser.stmt.mssql.TMssqlDeclare; 016import gudusoft.gsqlparser.util.IndexedLinkedHashMap; 017import gudusoft.gsqlparser.util.Logger; 018import gudusoft.gsqlparser.util.LoggerFactory; 019import gudusoft.gsqlparser.util.SQLUtil; 020 021import java.util.*; 022 023@SuppressWarnings({ "unchecked", "rawtypes" }) 024public class ModelBindingManager { 025 026 private static final Logger logger = LoggerFactory.getLogger(ModelBindingManager.class); 027 028 private final Map modelBindingMap = new LinkedHashMap(); 029 private final Map processModelBindingMap = new LinkedHashMap(); 030 private final Map viewModelBindingMap = new LinkedHashMap(); 031 private final Map insertModelBindingMap = new LinkedHashMap(); 032 private final Map createModelBindingMap = new LinkedHashMap(); 033 private final Map createModelQuickBindingMap = new LinkedHashMap(); 034 private final Map mergeModelBindingMap = new LinkedHashMap(); 035 private final Map updateModelBindingMap = new LinkedHashMap(); 036 private final Map cursorModelBindingMap = new LinkedHashMap(); 037 private final Map functionTableMap = new LinkedHashMap<>(); 038 private final Map tableNamesMap = new LinkedHashMap(); 039 private final Set<Table> dropTables = new HashSet<Table>(); 040 private final Map procedureNamesMap = new LinkedHashMap(); 041 private final Map oraclePackageNamesMap = new LinkedHashMap(); 042 private final Set<Relationship> relationHolder = Collections.synchronizedSet(new LinkedHashSet<Relationship>()); 043 private final Map<String, TTable> tableAliasMap = new LinkedHashMap(); 044 private final Map<TCustomSqlStatement, String> tableHashMap = new LinkedHashMap(); 045 private final Map<TCustomSqlStatement, String> topStmtHashMap = new HashMap(); 046 private final Map hashSQLMap = new HashMap(); 047 private final Map dynamicSQLMap = new HashMap(); 048 private final Set tableSet = new LinkedHashSet(); 049 private final Set resultSetSet = new LinkedHashSet(); 050 private final Set<String> dblinkTableSet = new LinkedHashSet(); 051 052 // Pipelined function stitching state 053 private final Map<String, List<String>> objectTypeIndex = new LinkedHashMap<>(); 054 private final Map<String, String> collectionToElementTypeIndex = new LinkedHashMap<>(); 055 private final Map<String, List<PipelinedFunctionSignature>> pipelinedSignatures = new LinkedHashMap<>(); 056 private final List<PendingPipelinedCallSite> pendingPipelinedCallSites = new ArrayList<>(); 057 private final Set<String> resolvingPipelinedFunctions = new HashSet<>(); 058 059 public Map<String, Long> DISPLAY_ID = new LinkedHashMap<String, Long>(); 060 public Map<Long, String> DISPLAY_NAME = new LinkedHashMap<Long, String>(); 061 public Map<String, String> virtualTableNames = new LinkedHashMap<String, String>(); 062 063 public long TABLE_COLUMN_ID = 0; 064 public long RELATION_ID = 0; 065 public int virtualTableIndex = -1; 066 067 private final static ThreadLocal localManager = new ThreadLocal(); 068 private final static ThreadLocal globalDatabase = new ThreadLocal(); 069 private final static ThreadLocal globalSchema = new ThreadLocal(); 070 private final static ThreadLocal globalVendor = new ThreadLocal(); 071 private final static ThreadLocal globalSQLEnv = new ThreadLocal(); 072 private final static ThreadLocal globalHash = new ThreadLocal(); 073 private final static ThreadLocal globalStmtStack = new ThreadLocal(); 074 private final static ThreadLocal globalSqlInfo = new ThreadLocal(); 075 private final static ThreadLocal globalOption = new ThreadLocal(); 076 private final static ThreadLocal globalOraclePackage = new ThreadLocal(); 077 private final static ThreadLocal globalProcedure = new ThreadLocal(); 078 079 public static void set(ModelBindingManager modelManager) { 080 if (modelManager != null) { 081 localManager.set(modelManager); 082 } 083 } 084 085 public static ModelBindingManager get() { 086 return (ModelBindingManager) localManager.get(); 087 } 088 089 public static void setGlobalDatabase(String database) { 090 if (database != null) { 091 globalDatabase.set(database); 092 } 093 } 094 095 public static String getGlobalDatabase() { 096 return (String) globalDatabase.get(); 097 } 098 099 public static void removeGlobalDatabase() { 100 globalDatabase.remove(); 101 } 102 103 public static void setGlobalSchema(String schema) { 104 if (schema != null) { 105 globalSchema.set(schema); 106 } 107 } 108 109 public static void removeGlobalSchema() { 110 globalSchema.remove(); 111 } 112 113 public static String getGlobalSchema() { 114 return (String) globalSchema.get(); 115 } 116 117 public static void setGlobalHash(String hash) { 118 if (hash != null) { 119 globalHash.set(hash); 120 } 121 } 122 123 public static void removeGlobalHash() { 124 globalHash.remove(); 125 } 126 127 public static String getGlobalHash() { 128 return (String) globalHash.get(); 129 } 130 131 public static void setGlobalOraclePackage(OraclePackage currentOraclePackage) { 132 if (currentOraclePackage != null) { 133 globalOraclePackage.set(currentOraclePackage); 134 } 135 } 136 137 public static void removeGlobalOraclePackage() { 138 globalOraclePackage.remove(); 139 } 140 141 public static OraclePackage getGlobalOraclePackage() { 142 return (OraclePackage) globalOraclePackage.get(); 143 } 144 145 public static void setGlobalProcedure(TStoredProcedureSqlStatement procedureSqlStatement) { 146 if (procedureSqlStatement != null) { 147 globalProcedure.set(procedureSqlStatement); 148 } 149 } 150 151 public static void removeGlobalProcedure() { 152 globalProcedure.remove(); 153 ModelBindingManager.get().cleanTempTable(); 154 } 155 156 public static TStoredProcedureSqlStatement getGlobalProcedure() { 157 return (TStoredProcedureSqlStatement) globalProcedure.get(); 158 } 159 160 public static void setGlobalVendor(EDbVendor vendor) { 161 if (vendor != null) { 162 globalVendor.set(vendor); 163 } 164 } 165 166 public static void removeGlobalVendor() { 167 globalVendor.remove(); 168 } 169 170 public static EDbVendor getGlobalVendor() { 171 return (EDbVendor) globalVendor.get(); 172 } 173 174 public static void setGlobalSQLEnv(TSQLEnv sqlenv) { 175 if (sqlenv != null) { 176 globalSQLEnv.set(sqlenv); 177 } 178 } 179 180 public static void removeGlobalSQLEnv() { 181 globalSQLEnv.remove(); 182 } 183 184 public static TSQLEnv getGlobalSQLEnv() { 185 return (TSQLEnv) globalSQLEnv.get(); 186 } 187 188 public static String getGlobalServer() { 189 TSQLEnv sqlEnv = getGlobalSQLEnv(); 190 if (sqlEnv != null) 191 return TSQLEnv.DEFAULT_SERVER_NAME.equals(sqlEnv.getDefaultServerName()) ? null : sqlEnv.getDefaultServerName(); 192 return null; 193 } 194 195 /** 196 * Resolve the effective default database (catalog) used to qualify 197 * unqualified / partial object names, with a three-tier precedence: 198 * 199 * <ol> 200 * <li>the active global database — an in-script {@code USE database}, or the 201 * per-group database set by {@code DataFlowAnalyzer};</li> 202 * <li>the per-analysis {@code Option.getDefaultDatabase()};</li> 203 * <li>the attached {@code TSQLEnv} default catalog;</li> 204 * <li>{@code TSQLEnv.DEFAULT_DB_NAME}.</li> 205 * </ol> 206 * 207 * Each lower tier is consulted only when the higher tier is null/empty. This 208 * lets a shared multi-catalog {@code TSQLEnv} be reused across analyses with 209 * different per-analysis default databases (tier 2) without mutating the env, 210 * while still honoring an in-script {@code USE database} (tier 1). 211 */ 212 public static String getEffectiveDefaultDatabase() { 213 // tier 1: active global database (USE database / per-group database) 214 String database = getGlobalDatabase(); 215 if (!SQLUtil.isEmpty(database)) { 216 return database; 217 } 218 // tier 2: per-analysis Option default database 219 Option option = getGlobalOption(); 220 if (option != null) { 221 String optionDatabase = option.getDefaultDatabase(); 222 if (!SQLUtil.isEmpty(optionDatabase) && !TSQLEnv.DEFAULT_DB_NAME.equals(optionDatabase)) { 223 return optionDatabase; 224 } 225 } 226 // tier 3: attached TSQLEnv default catalog 227 TSQLEnv sqlenv = getGlobalSQLEnv(); 228 if (sqlenv != null && !SQLUtil.isEmpty(sqlenv.getDefaultCatalogName())) { 229 return sqlenv.getDefaultCatalogName(); 230 } 231 // tier 4: fallback 232 return TSQLEnv.DEFAULT_DB_NAME; 233 } 234 235 public static void setGlobalStmtStack(Stack<TCustomSqlStatement> stack) { 236 if (stack != null) { 237 globalStmtStack.set(stack); 238 } 239 } 240 241 public static void removeGlobalStmtStack() { 242 globalStmtStack.remove(); 243 } 244 245 public static void setGlobalSqlInfo(IndexedLinkedHashMap<String, List<SqlInfo>> sqlInfoMap) { 246 if (sqlInfoMap != null) { 247 globalSqlInfo.set(sqlInfoMap); 248 } 249 } 250 251 public static void removeGlobalSqlInfo() { 252 globalSqlInfo.remove(); 253 } 254 255 public static IndexedLinkedHashMap<String, List<SqlInfo>> getGlobalSqlInfo() { 256 return (IndexedLinkedHashMap<String, List<SqlInfo>>) globalSqlInfo.get(); 257 } 258 259 public static void setGlobalOption(Option option) { 260 if (option != null) { 261 globalOption.set(option); 262 } 263 } 264 265 public static Option getGlobalOption() { 266 return (Option) globalOption.get(); 267 } 268 269 public static void removeGlobalOption() { 270 globalOption.remove(); 271 } 272 273 public static Stack<TCustomSqlStatement> getGlobalStmtStack() { 274 return (Stack<TCustomSqlStatement>) globalStmtStack.get(); 275 } 276 277 public static void remove() { 278 localManager.remove(); 279 globalDatabase.remove(); 280 globalSchema.remove(); 281 globalVendor.remove(); 282 globalSQLEnv.remove(); 283 globalHash.remove(); 284 globalStmtStack.remove(); 285 globalOption.remove(); 286 globalSqlInfo.remove(); 287 } 288 289 public void bindModel(Object gspModel, Object relationModel) { 290 if(gspModel == null) { 291 return; 292 } 293 modelBindingMap.put(gspModel, relationModel); 294 295 TTable table = null; 296 if (gspModel instanceof TTable && !(gspModel instanceof TCTE)) { 297 table = ((TTable) gspModel); 298 } else if (gspModel instanceof Table) { 299 table = ((Table) gspModel).getTableObject(); 300 } else if (gspModel instanceof QueryTable) { 301 table = ((QueryTable) gspModel).getTableObject(); 302 } else if (gspModel instanceof TCTE) { 303 TTableList tables = ((TCTE) gspModel).getPreparableStmt().tables; 304 for (int j = 0; j < tables.size(); j++) { 305 TTable item = tables.getTable(j); 306 if (item != null && !SQLUtil.isEmpty(item.getAliasName())) { 307 TCustomSqlStatement stmt = ((TCTE) gspModel).getPreparableStmt(); 308 if (tableHashMap.containsKey(stmt)) { 309 tableAliasMap.put( 310 tableHashMap.get(stmt) + ":" + DlineageUtil.getIdentifierNormalTableName(item.getAliasName()), 311 item); 312 } else { 313 String sql = stmt.toString(); 314 if(sql == null){ 315 System.err.println("Current statement toString() returns null."); 316 continue; 317 } 318 String hash = SHA256.getMd5(sql); 319 tableHashMap.put(stmt, hash); 320 tableAliasMap.put(hash + ":" + DlineageUtil.getIdentifierNormalTableName(item.getAliasName()), item); 321 } 322 } 323 324 if (item != null) { 325 tableSet.add(item); 326 } 327 } 328 } else if (gspModel instanceof Pair && ((Pair) gspModel).first instanceof Table) { 329 table = ((Table) ((Pair) gspModel).first).getTableObject(); 330 } 331 332 if (table == null && relationModel instanceof QueryTable) { 333 table = ((QueryTable) relationModel).getTableObject(); 334 } 335 336 updateTableAliasMap(table); 337 338 if (table != null) { 339 tableSet.add(table); 340 } 341 342 if(relationModel instanceof ResultSet) { 343 resultSetSet.add(relationModel); 344 } 345 } 346 347 protected void updateTableAliasMap(TTable table) { 348 if (table != null && !SQLUtil.isEmpty(table.getAliasName())) { 349 TCustomSqlStatement stmt = ModelBindingManager.getGlobalStmtStack().peek(); 350 if (tableHashMap.containsKey(stmt)) { 351 tableAliasMap.put(tableHashMap.get(stmt) + ":" + DlineageUtil.getIdentifierNormalTableName(table.getAliasName()), 352 table); 353 } else { 354 String sql = stmt.toString(); 355 if(sql == null){ 356 System.err.println("Current statement toString() returns null."); 357 } 358 else { 359 String hash = SHA256.getMd5(sql); 360 tableHashMap.put(stmt, hash); 361 tableAliasMap.put(hash + ":" + DlineageUtil.getIdentifierNormalTableName(table.getAliasName()), 362 table); 363 } 364 } 365 } 366 } 367 368 public Object getModel(Object gspModel) { 369 if (gspModel == null) { 370 return null; 371 } 372 373 if (gspModel instanceof TTable && !(gspModel instanceof TCTE)) { 374 TTable table = (TTable) gspModel; 375 if (table.getCTE() != null) { 376 Object result = modelBindingMap.get(table.getCTE()); 377 if (result != null) { 378 return result; 379 } 380 } 381 if (table.getAliasClause() != null && table.getAliasClause().getColumns() != null) { 382 Object result = modelBindingMap.get(table.getAliasClause().getColumns()); 383 if (result != null) { 384 return result; 385 } 386 } 387 if (table.getSubquery() != null && !table.getSubquery().isCombinedQuery()) { 388 Object result = modelBindingMap.get(table.getSubquery().getResultColumnList()); 389 if (result != null) { 390 return result; 391 } 392 } 393 } 394 if (gspModel instanceof TSelectSqlStatement) { 395 TSelectSqlStatement select = (TSelectSqlStatement) gspModel; 396 if (!select.isCombinedQuery()) { 397 if (select.getResultColumnList() != null) { 398 Object result = modelBindingMap.get(select.getResultColumnList()); 399 if (result != null) { 400 return result; 401 } 402 } 403 else if (select.getTransformClause() != null) { 404 Object result = modelBindingMap.get(select.getTransformClause()); 405 if (result != null) { 406 return result; 407 } 408 } 409 } 410 } 411 Object result = modelBindingMap.get(gspModel); 412 if (result == null) { 413 result = createModelBindingMap.get(gspModel); 414 } 415 if (result == null) { 416 result = insertModelBindingMap.get(gspModel); 417 } 418 if (result == null) { 419 result = updateModelBindingMap.get(gspModel); 420 } 421 if (result == null) { 422 result = mergeModelBindingMap.get(gspModel); 423 } 424 if (result == null) { 425 result = viewModelBindingMap.get(gspModel); 426 } 427 if (result == null) { 428 result = cursorModelBindingMap.get(gspModel); 429 } 430 431 if (result == null && gspModel instanceof TTable) { 432 result = getCreateTable((TTable) gspModel); 433 } 434 435 if (result == null && gspModel instanceof TTable) { 436 result = (Table) getCreateModel((TTable) gspModel); 437 } 438 439 if (result == null && gspModel instanceof TTable) { 440 TTable table = (TTable) gspModel; 441 if (table.getLinkTable() != null) { 442 result = (Table) getTableByName( 443 DlineageUtil.getTableFullName(table.getLinkTable().getTableName().toString())); 444 if (result == null) { 445 result = (Table) getTableByName( 446 DlineageUtil.getTableFullNameWithDefaultSchema(table.getLinkTable().getTableName().toString())); 447 } 448 } else { 449 result = (Table) getTableByName( 450 DlineageUtil.getTableFullName(((TTable) gspModel).getTableName().toString())); 451 if (result == null) { 452 result = (Table) getTableByName( 453 DlineageUtil.getTableFullNameWithDefaultSchema(((TTable) gspModel).getTableName().toString())); 454 } 455 } 456 } 457 458 if (result == null && gspModel instanceof TTable) { 459 TTable table = (TTable) gspModel; 460 if(table.getFuncCall()!=null) { 461 result = getModel(table.getFuncCall()); 462 } 463 } 464 465 if (result == null && gspModel instanceof TTable) { 466 TTable table = (TTable) gspModel; 467 Table tableModel = new Table(table); 468 result = (Table) getTableByName(DlineageUtil.getTableFullName(tableModel.getName())); 469 } 470 471 return result; 472 } 473 474 public List<Procedure> getProcedureModels(){ 475 List<Procedure> procedures = new ArrayList<Procedure>(); 476 for (Object obj : modelBindingMap.values()) { 477 if(obj instanceof Procedure && !procedures.contains(obj)){ 478 procedures.add((Procedure)obj); 479 } 480 } 481 return procedures; 482 } 483 484 public List<OraclePackage> getOraclePackageModels(){ 485 List<OraclePackage> oraclePackages = new ArrayList<OraclePackage>(); 486 for (Object obj : modelBindingMap.values()) { 487 if(obj instanceof OraclePackage && !oraclePackages.contains(obj)){ 488 oraclePackages.add((OraclePackage)obj); 489 } 490 } 491 return oraclePackages; 492 } 493 494 public List<Process> getProcessModels(){ 495 List<Process> processes = new ArrayList<Process>(); 496 for (Object obj : processModelBindingMap.values()) { 497 if(obj instanceof Process && !processes.contains(obj)){ 498 processes.add((Process)obj); 499 } 500 } 501 return processes; 502 } 503 504 public void bindProcessModel(TParseTreeNode gspModel, Object relationModel) { 505 processModelBindingMap.put(gspModel, relationModel); 506 } 507 508 public void unbindProcessModel(TParseTreeNode gspModel) { 509 processModelBindingMap.remove(gspModel); 510 } 511 512 public Process getProcessModel(TParseTreeNode gspModel) { 513 return (Process)processModelBindingMap.get(gspModel); 514 } 515 516 public void bindViewModel(Object gspModel, Object relationModel) { 517 viewModelBindingMap.put(gspModel, relationModel); 518 } 519 520 public Object getViewModel(Object gspModel) { 521 return viewModelBindingMap.get(gspModel); 522 } 523 524 public void bindUpdateModel(Object gspModel, Object relationModel) { 525 updateModelBindingMap.put(gspModel, relationModel); 526 } 527 528 public Object getUpdateModel(Object gspModel) { 529 return updateModelBindingMap.get(gspModel); 530 } 531 532 public void bindMergeModel(Object gspModel, Object relationModel) { 533 mergeModelBindingMap.put(gspModel, relationModel); 534 } 535 536 public Object getMergeModel(Object gspModel) { 537 return mergeModelBindingMap.get(gspModel); 538 } 539 540 public void bindInsertModel(Object gspModel, Object relationModel) { 541 insertModelBindingMap.put(gspModel, relationModel); 542 } 543 544 public Object getInsertModel(Object gspModel) { 545 return insertModelBindingMap.get(gspModel); 546 } 547 548 public void bindTableFunction(Object gspModel, Object functionTable) { 549 if (functionTableMap.containsKey(gspModel)) { 550 ((Set) functionTableMap.get(gspModel)).add(functionTable); 551 } else { 552 Set tableSet = new LinkedHashSet(); 553 tableSet.add(functionTable); 554 functionTableMap.put(gspModel, tableSet); 555 } 556 } 557 558 public Set<Object> getFunctionTable(Object gspModel) { 559 Set<Object> result = (Set<Object>)functionTableMap.get(gspModel); 560 if (result == null && gspModel instanceof String) { 561 for (Object key : functionTableMap.keySet()) { 562 if(!(key instanceof String)) { 563 continue; 564 } 565 String keyString = (String) key; 566 String modelString = (String) gspModel; 567 568 if (keyString.indexOf(".") != -1 && modelString.indexOf(".") == -1) { 569 keyString = keyString.substring(keyString.lastIndexOf(".") + 1); 570 if (keyString.equalsIgnoreCase(modelString)) { 571 return (Set<Object>)functionTableMap.get(key); 572 } 573 } 574 if (keyString.indexOf(".") == -1 && modelString.indexOf(".") != -1) { 575 modelString = modelString.substring(modelString.lastIndexOf(".") + 1); 576 if (keyString.equalsIgnoreCase(modelString)) { 577 return (Set<Object>)functionTableMap.get(key); 578 } 579 } 580 581 } 582 } 583 return result; 584 } 585 586 public Table getCreateTable(TTable table) { 587 if (table != null && table.getFullName() != null) { 588 return (Table) createModelQuickBindingMap.get(DlineageUtil.getTableFullName(table.getTableName().toString())); 589 } 590 if(modelBindingMap.get(table) instanceof Table) { 591 return (Table)modelBindingMap.get(table); 592 } 593 return null; 594 } 595 596 public Table getCreateModel(TTable table) { 597 return (Table) createModelBindingMap.get(table); 598 } 599 600 public void bindCreateModel(TTable table, Table tableModel) { 601 createModelBindingMap.put(table, tableModel); 602 if (!createModelQuickBindingMap.containsKey(DlineageUtil.getTableFullName(table.getTableName().toString()))) { 603 createModelQuickBindingMap.put(DlineageUtil.getTableFullName(table.getTableName().toString()), tableModel); 604 } 605 } 606 607 public void bindCreateModel(TObjectName tableName, Table tableModel) { 608 if (!createModelQuickBindingMap.containsKey(DlineageUtil.getTableFullName(tableName.toString()))) { 609 createModelQuickBindingMap.put(DlineageUtil.getTableFullName(tableName.toString()), tableModel); 610 } 611 } 612 613 public void bindCreateModel(String tableName, Table tableModel) { 614 if (!createModelQuickBindingMap.containsKey(DlineageUtil.getTableFullName(tableName))) { 615 createModelQuickBindingMap.put(DlineageUtil.getTableFullName(tableName), tableModel); 616 } 617 } 618 619 public TObjectName[] getTableColumns(TTable table) { 620 Table createTable = getCreateTable(table); 621 if (createTable != null) { 622 List<TableColumn> columnList = createTable.getColumns(); 623 TObjectName[] columns = new TObjectName[columnList.size()]; 624 for (int i = 0; i < columns.length; i++) { 625 columns[i] = columnList.get(i).getColumnObject(); 626 } 627 Arrays.sort(columns, new Comparator<TObjectName>() { 628 629 @Override 630 public int compare(TObjectName o1, TObjectName o2) { 631 if (o1 == null) { 632 return -1; 633 } 634 if (o2 == null) { 635 return 1; 636 } 637 return o1.getStartToken().posinlist - o2.getStartToken().posinlist; 638 } 639 }); 640 return columns; 641 } 642 else if(modelBindingMap.get(table) instanceof QueryTable) { 643 QueryTable queryTable = (QueryTable)modelBindingMap.get(table); 644 List<TObjectName> columns = new ArrayList<TObjectName>(); 645 for (ResultColumn resultColumn : queryTable.getColumns()) { 646 if(resultColumn.hasStarLinkColumn()) { 647 for(TObjectName column: resultColumn.getStarLinkColumnList()) { 648 columns.add(column); 649 } 650 } 651 else if (resultColumn.getColumnObject() instanceof TResultColumn) { 652 TResultColumn columnObject = ((TResultColumn) resultColumn.getColumnObject()); 653 TAliasClause alias = columnObject.getAliasClause(); 654 if (alias != null && alias.getAliasName() != null) { 655 if(resultColumn.isStruct() && resultColumn.getName().endsWith("*")) { 656 TObjectName structColumn = new TObjectName(); 657 structColumn.setString("*"); 658 columns.add(structColumn); 659 } 660 else { 661 columns.add(alias.getAliasName()); 662 } 663 } else { 664 if (columnObject.getFieldAttr() != null) { 665 columns.add(columnObject.getFieldAttr()); 666 } else { 667 TObjectName column = new TObjectName(); 668 if (columnObject.getExpr().getExpressionType() == EExpressionType.typecast_t) { 669 column.setString(columnObject.getExpr().getLeftOperand().toString()); 670 } else { 671 column.setString(columnObject.toString()); 672 } 673 columns.add(column); 674 } 675 } 676 } else if (resultColumn.getColumnObject() instanceof TObjectName) { 677 columns.add((TObjectName) resultColumn.getColumnObject()); 678 } 679 } 680 return columns.toArray(new TObjectName[0]); 681 } 682 683 TObjectNameList list = table.getLinkedColumns(); 684 List<TObjectName> columns = new ArrayList<TObjectName>(); 685 686 if (table.getCTE() != null) { 687 ResultSet resultSet = (ResultSet) getModel(table.getCTE()); 688 if (resultSet != null) { 689 List<ResultColumn> columnList = resultSet.getColumns(); 690 for (int i = 0; i < columnList.size(); i++) { 691 ResultColumn resultColumn = columnList.get(i); 692 if (resultColumn.getColumnObject() instanceof TResultColumn) { 693 TResultColumn columnObject = ((TResultColumn) resultColumn.getColumnObject()); 694 TAliasClause alias = columnObject.getAliasClause(); 695 if (alias != null && alias.getAliasName() != null) { 696 columns.add(alias.getAliasName()); 697 } else { 698 if (columnObject.getFieldAttr() != null) { 699 columns.add(columnObject.getFieldAttr()); 700 } else { 701 continue; 702 } 703 } 704 } else if (resultColumn.getColumnObject() instanceof TObjectName) { 705 columns.add((TObjectName) resultColumn.getColumnObject()); 706 } 707 } 708 } 709 } else if (list.size() == 1 && list.toString().indexOf("*") != -1 && table.getSubquery() != null) { 710 addSubqueryColumns(table, columns); 711 } else { 712 for (int i = 0; i < list.size(); i++) { 713 TObjectName object = list.getObjectName(i); 714 if (object.toString().indexOf("*") != -1 && table.getSubquery() != null) { 715 addSubqueryColumns(table, columns); 716 } 717 else 718 columns.add(object); 719 } 720 } 721 Collections.sort(columns, new Comparator<TObjectName>() { 722 723 @Override 724 public int compare(TObjectName o1, TObjectName o2) { 725 return o1.getStartToken().posinlist - o2.getStartToken().posinlist; 726 } 727 }); 728 return columns.toArray(new TObjectName[0]); 729 } 730 731 private void addSubqueryColumns(TTable table, List<TObjectName> columns) { 732 ResultSet resultSet = (ResultSet) getModel(table.getSubquery()); 733 if (resultSet != null) { 734 List<ResultColumn> columnList = resultSet.getColumns(); 735 for (int i = 0; i < columnList.size(); i++) { 736 ResultColumn resultColumn = columnList.get(i); 737 if (resultColumn.getColumnObject() instanceof TResultColumn) { 738 TResultColumn columnObject = ((TResultColumn) resultColumn.getColumnObject()); 739 TAliasClause alias = columnObject.getAliasClause(); 740 if (alias != null && alias.getAliasName() != null) { 741 columns.add(alias.getAliasName()); 742 } else { 743 if (columnObject.getFieldAttr() != null) { 744 columns.add(columnObject.getFieldAttr()); 745 } else { 746 TObjectName column = new TObjectName(); 747 if (columnObject.getExpr().getExpressionType() == EExpressionType.typecast_t) { 748 column.setString(columnObject.getExpr().getLeftOperand().toString()); 749 } else { 750 column.setString(columnObject.toString()); 751 } 752 columns.add(column); 753 } 754 } 755 } else if (resultColumn.getColumnObject() instanceof TObjectName) { 756 columns.add((TObjectName) resultColumn.getColumnObject()); 757 } 758 } 759 } 760 } 761 762 public TTable getTableFromColumn(TObjectName column) { 763 if (column.getSourceTable() != null) { 764 return column.getSourceTable(); 765 } 766 767 if (column.getTableString() != null && column.getTableString().trim().length() > 0) { 768 TCustomSqlStatement peekStmt = ModelBindingManager.getGlobalStmtStack().peek(); 769 while (peekStmt != null) { 770 TTable table = null; 771 if (tableHashMap.containsKey(peekStmt)) { 772 table = tableAliasMap.get(tableHashMap.get(peekStmt) + ":" 773 + DlineageUtil.getIdentifierNormalTableName(column.getTableString())); 774 } 775 if (table != null) { 776 return table; 777 } else { 778 peekStmt = peekStmt.getParentStmt(); 779 } 780 } 781 } 782 return null; 783 } 784 785 public TTable getTable(TCustomSqlStatement stmt, TObjectName column) { 786 if (column.getSourceTable() != null) { 787 return column.getSourceTable(); 788 } 789 790 if (column.getTableString() != null && column.getTableString().trim().length() > 0) { 791 TCustomSqlStatement peekStmt = ModelBindingManager.getGlobalStmtStack().peek(); 792 while (peekStmt != null) { 793 TTable table = null; 794 if (tableHashMap.containsKey(peekStmt)) { 795 table = tableAliasMap.get(tableHashMap.get(peekStmt) + ":" 796 + DlineageUtil.getIdentifierNormalTableName(column.getTableString())); 797 } 798 if (table != null && table.getSubquery() != stmt) 799 return table; 800 801 if (peekStmt.getTables() != null) { 802 for (TTable tableItem : peekStmt.getTables()) { 803 if (DlineageUtil.getIdentifierNormalTableName(tableItem.getTableName().toString()) 804 .equals(DlineageUtil.getIdentifierNormalTableName(column.getTableString()))) { 805 return tableItem; 806 } 807 } 808 } 809 810 peekStmt = peekStmt.getParentStmt(); 811 } 812 } 813 814 if (stmt.getTables() != null) { 815 for (int j = 0; j < stmt.getTables().size(); j++) { 816 TTable table = (TTable) stmt.getTables().getTable(j); 817 if (table.getSubquery() == stmt) 818 continue; 819 820 TObjectName[] columns = getTableColumns(table); 821 for (int i = 0; i < columns.length; i++) { 822 TObjectName columnName = columns[i]; 823 if (columnName == null || "*".equals(columnName.getColumnNameOnly())) 824 continue; 825 if (DlineageUtil.getIdentifierNormalColumnName(columnName.toString()) 826 .equals(DlineageUtil.getIdentifierNormalColumnName(column.toString()))) { 827 if (columnName.getSourceTable() == null || columnName.getSourceTable() == table) { 828 return table; 829 } 830 } 831 if (!SQLUtil.isEmpty(columnName.getColumnNameOnly()) 832 && DlineageUtil.getIdentifierNormalColumnName(columnName.getColumnNameOnly()) 833 .equals(DlineageUtil.getIdentifierNormalColumnName(column.getColumnNameOnly()))) { 834 if (columnName.getSourceTable() == null || columnName.getSourceTable() == table) { 835 return table; 836 } 837 } 838 } 839 } 840 } 841 842 // Iterator iter = tableSet.iterator(); 843 // while (iter.hasNext()) { 844 // TTable table = (TTable) iter.next(); 845 // 846 // if (table.getSubquery() == stmt) 847 // continue; 848 // 849 // if (table.getSubquery() != null) { 850 // int start = table.getSubquery().getStartToken().posinlist; 851 // int end = table.getSubquery().getEndToken().posinlist; 852 // if (start <= stmt.getStartToken().posinlist && end >= 853 // stmt.getEndToken().posinlist) { 854 // continue; 855 // } 856 // } 857 // 858 // TObjectName[] columns = getTableColumns(table); 859 // for (int i = 0; i < columns.length; i++) { 860 // TObjectName columnName = columns[i]; 861 // if (columnName == null || "*".equals(columnName.getColumnNameOnly())) 862 // continue; 863 // if 864 // (DlineageUtil.getIdentifierNormalName(columnName.toString()).equals(DlineageUtil.getIdentifierNormalName(column.toString()))) 865 // { 866 // if (columnName.getSourceTable() == null 867 // || columnName.getSourceTable() == table) { 868 // return table; 869 // } 870 // } 871 // if (columnName.getColumnNameOnly()!=null && 872 // DlineageUtil.getIdentifierNormalName(columnName.getColumnNameOnly()).equals(DlineageUtil.getIdentifierNormalName(column.getColumnNameOnly()))) 873 // { 874 // if (columnName.getSourceTable() == null 875 // || columnName.getSourceTable() == table) { 876 // return table; 877 // } 878 // } 879 // } 880 // } 881 return null; 882 } 883 884 public TTable guessTable(TCustomSqlStatement stmt, TObjectName column) { 885 if (column.getTableString() != null && column.getTableString().trim().length() > 0) { 886 TCustomSqlStatement peekStmt = ModelBindingManager.getGlobalStmtStack().peek(); 887 TTable table = null; 888 if (tableHashMap.containsKey(peekStmt)) { 889 table = tableAliasMap.get( 890 tableHashMap.get(peekStmt) + ":" + DlineageUtil.getIdentifierNormalTableName(column.getTableString())); 891 } 892 if (table != null && table.getSubquery() != stmt) 893 return table; 894 } 895 896 Iterator iter = tableSet.iterator(); 897 while (iter.hasNext()) { 898 TTable table = (TTable) iter.next(); 899 900 if (table.getSubquery() == stmt) 901 continue; 902 903 TObjectName[] columns = getTableColumns(table); 904 for (int i = 0; i < columns.length; i++) { 905 TObjectName columnName = columns[i]; 906 if ("*".equals(columnName.getColumnNameOnly())) 907 continue; 908 if (columnName.toString().equalsIgnoreCase(column.toString())) { 909 if (columnName.getSourceTable() == null || columnName.getSourceTable() == table) { 910 return table; 911 } 912 } 913 } 914 } 915 return null; 916 } 917 918 public List<Table> getTablesByName() { 919 List<Table> tables = new ArrayList<Table>(); 920 Iterator iter = tableNamesMap.values().iterator(); 921 while (iter.hasNext()) { 922 tables.add((Table) iter.next()); 923 } 924 return tables; 925 } 926 927 public List<TTable> getBaseTables() { 928 List<TTable> tables = new ArrayList<TTable>(); 929 930 Iterator iter = modelBindingMap.keySet().iterator(); 931 while (iter.hasNext()) { 932 Object key = iter.next(); 933 if (!(key instanceof TTable)) { 934 continue; 935 } 936 TTable table = (TTable) key; 937 if (table.getSubquery() == null) { 938 tables.add(table); 939 } 940 } 941 942 iter = createModelBindingMap.keySet().iterator(); 943 while (iter.hasNext()) { 944 Object key = iter.next(); 945 if (!(key instanceof TTable)) { 946 continue; 947 } 948 TTable table = (TTable) key; 949 tables.add(table); 950 } 951 952 iter = insertModelBindingMap.keySet().iterator(); 953 while (iter.hasNext()) { 954 Object key = iter.next(); 955 if (!(key instanceof TTable)) { 956 continue; 957 } 958 TTable table = (TTable) key; 959 tables.add(table); 960 } 961 962 iter = mergeModelBindingMap.keySet().iterator(); 963 while (iter.hasNext()) { 964 Object key = iter.next(); 965 if (!(key instanceof TTable)) { 966 continue; 967 } 968 TTable table = (TTable) key; 969 tables.add(table); 970 } 971 972 iter = updateModelBindingMap.keySet().iterator(); 973 while (iter.hasNext()) { 974 Object key = iter.next(); 975 if (!(key instanceof TTable)) { 976 continue; 977 } 978 TTable table = (TTable) key; 979 if (!tables.contains(table)) { 980 tables.add(table); 981 } 982 } 983 984 return tables; 985 } 986 987 public List<TCustomSqlStatement> getViews() { 988 List<TCustomSqlStatement> views = new ArrayList<TCustomSqlStatement>(); 989 990 Iterator iter = viewModelBindingMap.keySet().iterator(); 991 while (iter.hasNext()) { 992 Object key = iter.next(); 993 if (!(key instanceof TCreateViewSqlStatement) && !(key instanceof TCreateMaterializedSqlStatement)) { 994 continue; 995 } 996 TCustomSqlStatement view = (TCustomSqlStatement) key; 997 if (!views.contains(view)) { 998 views.add(view); 999 } 1000 } 1001 return views; 1002 } 1003 1004 public List<TResultColumnList> getSelectResultSets() { 1005 List<TResultColumnList> resultSets = new ArrayList<TResultColumnList>(); 1006 1007 Iterator iter = modelBindingMap.keySet().iterator(); 1008 while (iter.hasNext()) { 1009 Object key = iter.next(); 1010 if (!(key instanceof TResultColumnList)) { 1011 continue; 1012 } 1013 TResultColumnList resultset = (TResultColumnList) key; 1014 resultSets.add(resultset); 1015 } 1016 return resultSets; 1017 } 1018 1019 public List<TObjectNameList> getQueryAliasTables() { 1020 List<TObjectNameList> resultSets = new ArrayList<TObjectNameList>(); 1021 1022 Iterator iter = modelBindingMap.keySet().iterator(); 1023 while (iter.hasNext()) { 1024 Object key = iter.next(); 1025 if (!(key instanceof TObjectNameList)) { 1026 continue; 1027 } 1028 TObjectNameList resultset = (TObjectNameList) key; 1029 resultSets.add(resultset); 1030 } 1031 return resultSets; 1032 } 1033 1034 public List<TSelectSqlStatement> getSelectSetResultSets() { 1035 List<TSelectSqlStatement> resultSets = new ArrayList<TSelectSqlStatement>(); 1036 1037 Iterator iter = modelBindingMap.keySet().iterator(); 1038 while (iter.hasNext()) { 1039 Object key = iter.next(); 1040 if (!(key instanceof TSelectSqlStatement)) { 1041 continue; 1042 } 1043 1044 TSelectSqlStatement stmt = (TSelectSqlStatement) key; 1045 if (stmt.getSetOperatorType() == ESetOperatorType.none) 1046 continue; 1047 1048 resultSets.add(stmt); 1049 } 1050 return resultSets; 1051 } 1052 1053 public List<TCTE> getCTEs() { 1054 List<TCTE> resultSets = new ArrayList<TCTE>(); 1055 1056 Iterator iter = modelBindingMap.keySet().iterator(); 1057 while (iter.hasNext()) { 1058 Object key = iter.next(); 1059 if (!(key instanceof TCTE)) { 1060 continue; 1061 } 1062 1063 TCTE cte = (TCTE) key; 1064 resultSets.add(cte); 1065 } 1066 return resultSets; 1067 } 1068 1069 public List<TTable> getTableWithSelectSetResultSets() { 1070 List<TTable> resultSets = new ArrayList<TTable>(); 1071 1072 Iterator iter = modelBindingMap.keySet().iterator(); 1073 while (iter.hasNext()) { 1074 Object key = iter.next(); 1075 if (!(key instanceof TTable)) { 1076 continue; 1077 } 1078 1079 if (((TTable) key).getSubquery() == null) 1080 continue; 1081 TSelectSqlStatement stmt = ((TTable) key).getSubquery(); 1082 if (stmt.getSetOperatorType() == ESetOperatorType.none) 1083 continue; 1084 1085 resultSets.add((TTable) key); 1086 } 1087 return resultSets; 1088 } 1089 1090 public List<TParseTreeNode> getMergeResultSets() { 1091 List<TParseTreeNode> resultSets = new ArrayList<TParseTreeNode>(); 1092 1093 Iterator iter = modelBindingMap.keySet().iterator(); 1094 while (iter.hasNext()) { 1095 Object key = iter.next(); 1096 if (!(key instanceof TMergeUpdateClause) && !(key instanceof TMergeInsertClause)) { 1097 continue; 1098 } 1099 TParseTreeNode resultset = (TParseTreeNode) key; 1100 resultSets.add(resultset); 1101 } 1102 return resultSets; 1103 } 1104 1105 public List<TParseTreeNode> getOutputResultSets() { 1106 List<TParseTreeNode> resultSets = new ArrayList<TParseTreeNode>(); 1107 1108 Iterator iter = modelBindingMap.keySet().iterator(); 1109 while (iter.hasNext()) { 1110 Object key = iter.next(); 1111 if (!(key instanceof TOutputClause)) { 1112 continue; 1113 } 1114 TParseTreeNode resultset = (TParseTreeNode) key; 1115 resultSets.add(resultset); 1116 } 1117 return resultSets; 1118 } 1119 1120 public List<TParseTreeNode> getUpdateResultSets() { 1121 List<TParseTreeNode> resultSets = new ArrayList<TParseTreeNode>(); 1122 1123 Iterator iter = modelBindingMap.keySet().iterator(); 1124 while (iter.hasNext()) { 1125 Object key = iter.next(); 1126 if (!(key instanceof TUpdateSqlStatement)) { 1127 continue; 1128 } 1129 TParseTreeNode resultset = (TParseTreeNode) key; 1130 resultSets.add(resultset); 1131 } 1132 return resultSets; 1133 } 1134 1135 public List<TParseTreeNode> getFunctoinCalls() { 1136 List<TParseTreeNode> resultSets = new ArrayList<TParseTreeNode>(); 1137 1138 Iterator iter = modelBindingMap.keySet().iterator(); 1139 while (iter.hasNext()) { 1140 Object key = iter.next(); 1141 if (!(key instanceof TFunctionCall) && !(key instanceof TCaseExpression)) { 1142 continue; 1143 } 1144 TParseTreeNode resultset = (TParseTreeNode) key; 1145 resultSets.add(resultset); 1146 } 1147 return resultSets; 1148 } 1149 1150 public List<TParseTreeNode> getAliases() { 1151 List<TParseTreeNode> resultSets = new ArrayList<TParseTreeNode>(); 1152 1153 Iterator iter = modelBindingMap.keySet().iterator(); 1154 while (iter.hasNext()) { 1155 Object key = iter.next(); 1156 if (!(key instanceof TAliasClause)) { 1157 continue; 1158 } 1159 TParseTreeNode resultset = (TParseTreeNode) key; 1160 resultSets.add(resultset); 1161 } 1162 return resultSets; 1163 } 1164 1165 public List<TParseTreeNode> getCursors() { 1166 List<TParseTreeNode> resultSets = new ArrayList<TParseTreeNode>(); 1167 1168 Iterator iter = modelBindingMap.keySet().iterator(); 1169 while (iter.hasNext()) { 1170 Object key = iter.next(); 1171 if (!(key instanceof TCursorDeclStmt) && !(key instanceof TOpenforStmt)) { 1172 continue; 1173 } 1174 TParseTreeNode resultset = (TParseTreeNode) key; 1175 resultSets.add(resultset); 1176 } 1177 return resultSets; 1178 } 1179 1180 public List<TParseTreeNode> getPivotdTables() { 1181 List<TParseTreeNode> resultSets = new ArrayList<TParseTreeNode>(); 1182 1183 Iterator iter = modelBindingMap.keySet().iterator(); 1184 while (iter.hasNext()) { 1185 Object key = iter.next(); 1186 if (!(key instanceof TPivotClause)) { 1187 continue; 1188 } 1189 TParseTreeNode resultset = (TParseTreeNode) key; 1190 resultSets.add(resultset); 1191 } 1192 return resultSets; 1193 } 1194 1195 public void addRelation(Relationship relation) { 1196 if (relation != null && !relationHolder.contains(relation)) { 1197 relationHolder.add(relation); 1198 } 1199 } 1200 1201 public void removeRelation(ImpactRelationship relation) { 1202 if (relation != null) { 1203 relationHolder.remove(relation); 1204 } 1205 } 1206 1207 public Relationship[] getRelations() { 1208 return relationHolder.toArray(new Relationship[0]); 1209 } 1210 1211 public void reset() { 1212 modelBindingMap.clear(); 1213 processModelBindingMap.clear(); 1214 viewModelBindingMap.clear(); 1215 insertModelBindingMap.clear(); 1216 createModelBindingMap.clear(); 1217 createModelQuickBindingMap.clear(); 1218 mergeModelBindingMap.clear(); 1219 updateModelBindingMap.clear(); 1220 cursorModelBindingMap.clear(); 1221 functionTableMap.clear(); 1222 tableNamesMap.clear(); 1223 dropTables.clear(); 1224 procedureNamesMap.clear(); 1225 oraclePackageNamesMap.clear(); 1226 relationHolder.clear(); 1227 tableAliasMap.clear(); 1228 tableHashMap.clear(); 1229 topStmtHashMap.clear(); 1230 hashSQLMap.clear(); 1231 dynamicSQLMap.clear(); 1232 tableSet.clear(); 1233 resultSetSet.clear(); 1234 dblinkTableSet.clear(); 1235 objectTypeIndex.clear(); 1236 collectionToElementTypeIndex.clear(); 1237 pipelinedSignatures.clear(); 1238 pendingPipelinedCallSites.clear(); 1239 resolvingPipelinedFunctions.clear(); 1240 DISPLAY_ID.clear(); 1241 DISPLAY_NAME.clear(); 1242 virtualTableNames.clear(); 1243 } 1244 1245 public void bindCursorModel(TCursorDeclStmt stmt, Variable resultSet) { 1246 String procedureName = DlineageUtil.getProcedureParentName(stmt); 1247 String variableString = stmt.getCursorName().toString(); 1248 if (variableString.startsWith(":")) { 1249 variableString = variableString.substring(variableString.indexOf(":") + 1); 1250 } 1251 if (!SQLUtil.isEmpty(procedureName)) { 1252 variableString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString); 1253 } 1254 createModelBindingMap.put(DlineageUtil.getTableFullName(variableString), resultSet); 1255 } 1256 1257 public void bindCursorModel(TMssqlDeclare stmt, Variable resultSet) { 1258 String procedureName = DlineageUtil.getProcedureParentName(stmt); 1259 String variableString = stmt.getCursorName().toString(); 1260 if (variableString.startsWith(":")) { 1261 variableString = variableString.substring(variableString.indexOf(":") + 1); 1262 } 1263 if (!SQLUtil.isEmpty(procedureName)) { 1264 variableString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString); 1265 } 1266 createModelBindingMap.put(DlineageUtil.getTableFullName(variableString), resultSet); 1267 } 1268 1269 public void bindCursorModel(TOpenforStmt stmt, Variable resultSet) { 1270 String procedureName = DlineageUtil.getProcedureParentName(stmt); 1271 String variableString = stmt.getCursorVariableName().toString(); 1272 if (variableString.startsWith(":")) { 1273 variableString = variableString.substring(variableString.indexOf(":") + 1); 1274 } 1275 if (!SQLUtil.isEmpty(procedureName)) { 1276 variableString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString); 1277 } 1278 createModelBindingMap.put(DlineageUtil.getTableFullName(variableString), resultSet); 1279 } 1280 1281 public void bindCursorModel(TForStmt stmt, Variable resultSet) { 1282 String procedureName = DlineageUtil.getProcedureParentName(stmt); 1283 String variableString = stmt.getCursorName().toString(); 1284 if (variableString.startsWith(":")) { 1285 variableString = variableString.substring(variableString.indexOf(":") + 1); 1286 } 1287 if (!SQLUtil.isEmpty(procedureName)) { 1288 variableString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString); 1289 } 1290 createModelBindingMap.put(DlineageUtil.getTableFullName(variableString), resultSet); 1291 } 1292 1293 public void bindCursorModel(TLoopStmt stmt, Variable resultSet) { 1294 String procedureName = DlineageUtil.getProcedureParentName(stmt); 1295 String variableString = stmt.getRecordName().toString(); 1296 if (variableString.startsWith(":")) { 1297 variableString = variableString.substring(variableString.indexOf(":") + 1); 1298 } 1299 if (!SQLUtil.isEmpty(procedureName)) { 1300 variableString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString); 1301 } 1302 createModelBindingMap.put(DlineageUtil.getTableFullName(variableString), resultSet); 1303 } 1304 1305 public void bindCursorIndex(TObjectName indexName, TObjectName cursorName) { 1306 TCustomSqlStatement stmt = getGlobalStmtStack().peek(); 1307 String procedureName = DlineageUtil.getProcedureParentName(stmt); 1308 String variableString = cursorName.toString(); 1309 if (variableString.startsWith(":")) { 1310 variableString = variableString.substring(variableString.indexOf(":") + 1); 1311 } 1312 if (!SQLUtil.isEmpty(procedureName)) { 1313 variableString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString); 1314 } 1315 1316 Cursor cursor = ((Cursor) createModelBindingMap 1317 .get(DlineageUtil.getTableFullName(variableString))); 1318 if (cursor != null) { 1319 String indexNameString = indexName.toString(); 1320 if (!SQLUtil.isEmpty(procedureName)) { 1321 indexNameString = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(indexNameString); 1322 } 1323 bindModel(DlineageUtil.getTableFullName(indexNameString), 1324 modelBindingMap.get(cursor.getResultColumnObject())); 1325 bindTableByName(DlineageUtil.getTableFullName(indexNameString), 1326 cursor); 1327 } 1328 } 1329 1330 public List<TStoredProcedureSqlStatement> getProcedures() { 1331 List<TStoredProcedureSqlStatement> procedures = new ArrayList(); 1332 Iterator iter = this.modelBindingMap.keySet().iterator(); 1333 1334 while (iter.hasNext()) { 1335 Object key = iter.next(); 1336 if (key instanceof TStoredProcedureSqlStatement) { 1337 TStoredProcedureSqlStatement procedure = (TStoredProcedureSqlStatement) key; 1338 procedures.add(procedure); 1339 } 1340 } 1341 1342 return procedures; 1343 } 1344 1345 // public void bindTableByName(TObjectName tableName, Table tableModel) { 1346 // tableNamesMap.put(tableName, tableModel); 1347 // 1348 // } 1349 // 1350 public void bindTableByName(String tableName, Table tableModel) { 1351 tableNamesMap.put(tableName, tableModel); 1352 1353 } 1354 1355 // public Table getTableByName(TObjectName tableName) { 1356 // return (Table)tableNamesMap.get(tableName); 1357 // } 1358 1359 public Table getTableByName(String tableName) { 1360 if (tableName == null) { 1361 return null; 1362 } 1363 Table table = (Table) tableNamesMap.get(tableName); 1364 if (table == null) { 1365 Stack<TCustomSqlStatement> stmtStack = getGlobalStmtStack(); 1366 if (stmtStack.isEmpty()) { 1367 return (Table) tableNamesMap.get(DlineageUtil.getTableFullName(tableName.toString())); 1368 } 1369 TCustomSqlStatement stmt = stmtStack.peek(); 1370 String procedureName = DlineageUtil.getProcedureParentName(stmt); 1371 String variableString = tableName.toString(); 1372 if (!SQLUtil.isEmpty(procedureName)) { 1373 String variableWithProcedure = DlineageUtil.getTableFullName(procedureName) + "." + SQLUtil.getIdentifierNormalTableName(variableString); 1374 if(tableNamesMap.containsKey(DlineageUtil.getTableFullName(variableWithProcedure))) { 1375 return (Table) tableNamesMap.get(DlineageUtil.getTableFullName(variableWithProcedure)); 1376 } 1377 } 1378 return (Table) tableNamesMap.get(DlineageUtil.getTableFullName(variableString)); 1379 } else { 1380 return table; 1381 } 1382 } 1383 1384 1385 public void bindProcedureByName(String procedureName, Procedure procedureModel) { 1386 procedureNamesMap.put(procedureName, procedureModel); 1387 1388 } 1389 1390 public Procedure getProcedureByName(String procedureName) { 1391 if(procedureName == null){ 1392 return null; 1393 } 1394 1395 if (ModelBindingManager.getGlobalOraclePackage() != null 1396 && !procedureName.startsWith(ModelBindingManager.getGlobalOraclePackage().getName())) { 1397 procedureName = ModelBindingManager.getGlobalOraclePackage().getName() + "." + procedureName; 1398 } 1399 Procedure procedure = (Procedure) procedureNamesMap.get(procedureName); 1400 if (procedure == null) { 1401 if (procedureName.indexOf("(") == -1) { 1402 for (Object name : procedureNamesMap.keySet()) { 1403 String fuctionName = name.toString(); 1404 if (fuctionName.startsWith(procedureName + "(")) { 1405 return (Procedure) procedureNamesMap.get(name); 1406 } 1407 if (fuctionName.indexOf(".") != -1 && procedureName.indexOf(".") == -1) { 1408 fuctionName = fuctionName.substring(fuctionName.lastIndexOf(".") + 1); 1409 if (fuctionName.startsWith(procedureName + "(")) { 1410 return (Procedure) procedureNamesMap.get(name); 1411 } 1412 } 1413 if (fuctionName.indexOf(".") == -1 && procedureName.indexOf(".") != -1) { 1414 String procedureNameSubstring = procedureName.substring(procedureName.lastIndexOf(".") + 1); 1415 if (fuctionName.startsWith(procedureNameSubstring + "(")) { 1416 return (Procedure) procedureNamesMap.get(name); 1417 } 1418 } 1419 } 1420 } 1421 else { 1422 for (Object name : procedureNamesMap.keySet()) { 1423 String fuctionName = name.toString(); 1424 if (fuctionName.startsWith(procedureName)) { 1425 return (Procedure) procedureNamesMap.get(name); 1426 } 1427 if (fuctionName.indexOf(".") != -1 && procedureName.indexOf(".") == -1) { 1428 fuctionName = fuctionName.substring(fuctionName.lastIndexOf(".") + 1); 1429 if (fuctionName.equalsIgnoreCase(procedureName)) { 1430 return (Procedure) procedureNamesMap.get(name); 1431 } 1432 } 1433 if (fuctionName.indexOf(".") == -1 && procedureName.indexOf(".") != -1) { 1434 String procedureNameSubstring = procedureName.substring(procedureName.lastIndexOf(".") + 1); 1435 if (fuctionName.equalsIgnoreCase(procedureNameSubstring)) { 1436 return (Procedure) procedureNamesMap.get(name); 1437 } 1438 } 1439 } 1440 } 1441 } 1442 return procedure; 1443 } 1444 1445 public void bindOraclePackageByName(String oraclePackageName, OraclePackage oraclePackageModel) { 1446 oraclePackageNamesMap.put(oraclePackageName, oraclePackageModel); 1447 1448 } 1449 1450 public OraclePackage getOraclePackageByName(String oraclePackageName) { 1451 return (OraclePackage) oraclePackageNamesMap.get(oraclePackageName); 1452 } 1453 1454 1455 public String getSqlHash(TCustomSqlStatement stmt) { 1456 return topStmtHashMap.get(stmt); 1457 } 1458 1459 public Map getHashSQLMap() { 1460 return hashSQLMap; 1461 } 1462 1463 public Map getDynamicSQLMap() { 1464 return dynamicSQLMap; 1465 } 1466 1467 public void collectSqlHash(TCustomSqlStatement stmt) { 1468 if (getGlobalOption().getAnalyzeMode() == AnalyzeMode.crud) { 1469 String sql = stmt.toString(); 1470 if (sql != null) { 1471 sql = stmt.getStartToken().lineNo + ":" + sql; 1472 String hash = SQLUtil.stringToMD5(sql); 1473 topStmtHashMap.put(stmt, hash); 1474 hashSQLMap.put(hash, new Pair3<Long, Long, String>(stmt.getStartToken().lineNo, stmt.getEndToken().lineNo, ModelBindingManager.getGlobalHash())); 1475 } 1476 } else { 1477 try { 1478 String sql = stmt.asCanonical(); 1479 if (sql != null) { 1480 String hash = SQLUtil.stringToMD5(sql); 1481 topStmtHashMap.put(stmt, hash); 1482 hashSQLMap.put(hash, sql); 1483 } 1484 } catch (Exception e) { 1485 logger.error("collectSqlHash error: " + e.getMessage(), e); 1486 } 1487 } 1488 } 1489 1490 public void collectDynamicSqlHash(TCustomSqlStatement stmt) { 1491 if (getGlobalOption().getAnalyzeMode() == AnalyzeMode.dynamic) { 1492 String sql = stmt.toString(); 1493 if (sql != null) { 1494 sql = stmt.getStartToken().lineNo + ":" + sql; 1495 String hash = SQLUtil.stringToMD5(sql); 1496 dynamicSQLMap.put(hash, new Pair3<Long, Long, String>(stmt.getStartToken().lineNo, stmt.getEndToken().lineNo, ModelBindingManager.getGlobalHash())); 1497 } 1498 } 1499 } 1500 1501 public void appendDblinkTable(String name) { 1502 if (!SQLUtil.isEmpty(name)) { 1503 dblinkTableSet.add(name); 1504 } 1505 } 1506 1507 public boolean isDblinkTable(String name) { 1508 return dblinkTableSet.contains(name); 1509 } 1510 1511 public Set<ResultSet> getResultSets() { 1512 return resultSetSet; 1513 } 1514 1515 public void dropTable(Table table) { 1516 List tableNames = new ArrayList(tableNamesMap.keySet()); 1517 for (Object tableName : tableNames) { 1518 if(tableNamesMap.get(tableName) == table) { 1519 tableNamesMap.remove(tableName); 1520 dropTables.add(table); 1521 } 1522 } 1523 } 1524 1525 public void cleanTempTable() { 1526 Iterator<String> iter = tableNamesMap.keySet().iterator(); 1527 while(iter.hasNext()) { 1528 String tableName = iter.next(); 1529 if(DlineageUtil.isTempTable((Table)tableNamesMap.get(tableName), getGlobalVendor())) { 1530 dropTables.add((Table)tableNamesMap.get(tableName)); 1531 iter.remove(); 1532 } 1533 } 1534 } 1535 1536 public Set<Table> getDropTables() { 1537 return dropTables; 1538 } 1539 1540 // --- Pipelined function stitching methods --- 1541 1542 public void indexObjectType(String normalizedName, List<String> fieldNames) { 1543 objectTypeIndex.put(normalizedName, fieldNames); 1544 } 1545 1546 public List<String> getObjectTypeFields(String normalizedName) { 1547 return objectTypeIndex.get(normalizedName); 1548 } 1549 1550 public void indexCollectionType(String collectionName, String elementTypeName) { 1551 collectionToElementTypeIndex.put(collectionName, elementTypeName); 1552 } 1553 1554 public String getElementTypeName(String collectionName) { 1555 return collectionToElementTypeIndex.get(collectionName); 1556 } 1557 1558 public void addPipelinedSignature(PipelinedFunctionSignature sig) { 1559 pipelinedSignatures.computeIfAbsent(sig.getFunctionKey(), k -> new ArrayList<>()).add(sig); 1560 if (sig.getNakedKey() != null && !sig.getNakedKey().equals(sig.getFunctionKey())) { 1561 pipelinedSignatures.computeIfAbsent(sig.getNakedKey(), k -> new ArrayList<>()).add(sig); 1562 } 1563 } 1564 1565 public PipelinedFunctionSignature findPipelinedSignature(List<String> candidates, int argCount) { 1566 for (String key : candidates) { 1567 List<PipelinedFunctionSignature> sigs = pipelinedSignatures.get(key); 1568 if (sigs != null) { 1569 PipelinedFunctionSignature match = null; 1570 for (PipelinedFunctionSignature sig : sigs) { 1571 if (sig.getArgCount() == argCount || argCount < 0) { 1572 if (match != null) { 1573 return null; // ambiguous 1574 } 1575 match = sig; 1576 } 1577 } 1578 if (match != null) { 1579 return match; 1580 } 1581 } 1582 } 1583 return null; 1584 } 1585 1586 public PipelinedFunctionSignature findPipelinedSignatureAny(List<String> candidates) { 1587 for (String key : candidates) { 1588 List<PipelinedFunctionSignature> sigs = pipelinedSignatures.get(key); 1589 if (sigs != null && !sigs.isEmpty()) { 1590 if (sigs.size() == 1) { 1591 return sigs.get(0); 1592 } 1593 } 1594 } 1595 return null; 1596 } 1597 1598 public void addPendingPipelinedCallSite(PendingPipelinedCallSite callSite) { 1599 pendingPipelinedCallSites.add(callSite); 1600 } 1601 1602 public List<PendingPipelinedCallSite> getPendingPipelinedCallSites() { 1603 return pendingPipelinedCallSites; 1604 } 1605 1606 public Set<String> getResolvingPipelinedFunctions() { 1607 return resolvingPipelinedFunctions; 1608 } 1609 1610 public Map<String, List<PipelinedFunctionSignature>> getPipelinedSignatures() { 1611 return pipelinedSignatures; 1612 } 1613 1614}