001package gudusoft.gsqlparser.dlineage.util; 002 003import java.io.File; 004import java.util.ArrayList; 005import java.util.Arrays; 006import java.util.LinkedHashSet; 007import java.util.List; 008import java.util.Map; 009import java.util.Set; 010 011import gudusoft.gsqlparser.EDbVendor; 012import gudusoft.gsqlparser.EParameterMode; 013import gudusoft.gsqlparser.TCustomSqlStatement; 014import gudusoft.gsqlparser.dlineage.dataflow.model.AnalyzeMode; 015import gudusoft.gsqlparser.dlineage.dataflow.model.ModelBindingManager; 016import gudusoft.gsqlparser.dlineage.dataflow.model.Option; 017import gudusoft.gsqlparser.dlineage.dataflow.model.SqlInfo; 018import gudusoft.gsqlparser.dlineage.dataflow.model.SubType; 019import gudusoft.gsqlparser.dlineage.dataflow.model.Table; 020import gudusoft.gsqlparser.dlineage.dataflow.model.xml.*; 021import gudusoft.gsqlparser.nodes.TFunctionCall; 022import gudusoft.gsqlparser.nodes.TObjectName; 023import gudusoft.gsqlparser.nodes.TParameterDeclaration; 024import gudusoft.gsqlparser.nodes.TParameterDeclarationList; 025import gudusoft.gsqlparser.sqlenv.ESQLDataObjectType; 026import gudusoft.gsqlparser.sqlenv.TSQLEnv; 027import gudusoft.gsqlparser.stmt.TCommonBlock; 028import gudusoft.gsqlparser.stmt.TSelectSqlStatement; 029import gudusoft.gsqlparser.stmt.TStoredProcedureSqlStatement; 030import gudusoft.gsqlparser.stmt.oracle.TPlsqlCreatePackage; 031import gudusoft.gsqlparser.TBaseType; 032import gudusoft.gsqlparser.util.SQLUtil; 033import gudusoft.gsqlparser.stmt.teradata.TTeradataCreateProcedure; 034import gudusoft.gsqlparser.util.SQLUtil; 035import gudusoft.gsqlparser.util.functionChecker; 036import gudusoft.gsqlparser.util.keywordChecker; 037import gudusoft.gsqlparser.util.json.JSON; 038 039public class DlineageUtil { 040 041 public static boolean compareIdentifier(String source, String target, ESQLDataObjectType sqlDataObjectType) { 042 return SQLUtil.compareIdentifier(ModelBindingManager.getGlobalVendor(), sqlDataObjectType, source, target); 043 } 044 045 public static boolean compareColumnIdentifier(String source, String target) { 046 return SQLUtil.compareIdentifier(ModelBindingManager.getGlobalVendor(), ESQLDataObjectType.dotColumn, source, 047 target); 048 } 049 050 public static boolean compareTableIdentifier(String source, String target) { 051 return SQLUtil.compareIdentifier(ModelBindingManager.getGlobalVendor(), ESQLDataObjectType.dotTable, source, 052 target); 053 } 054 055 public static String getIdentifierNormalColumnName(String name) { 056 EDbVendor dbVendor = ModelBindingManager.getGlobalVendor(); 057 return SQLUtil.getIdentifierNormalName(dbVendor, name, ESQLDataObjectType.dotColumn); 058 } 059 060 public static String getIdentifierNormalColumnName(String name, EDbVendor dbVendor) { 061 return SQLUtil.getIdentifierNormalName(dbVendor, name, ESQLDataObjectType.dotColumn); 062 } 063 064 public static String normalizeColumnName(String name) { 065 return SQLUtil.normalizeIdentifier(ModelBindingManager.getGlobalVendor(), ESQLDataObjectType.dotColumn, name); 066 } 067 068 public static String normalizeColumnName(String name, EDbVendor dbVendor) { 069 return SQLUtil.normalizeIdentifier(dbVendor, ESQLDataObjectType.dotColumn, name); 070 } 071 072 073 public static String getIdentifierNormalTableName(String name) { 074 if (name == null) { 075 return null; 076 } 077 if (ModelBindingManager.get() != null && ModelBindingManager.get().isDblinkTable(name)) { 078 int index = name.lastIndexOf("@"); 079 if (index > 0) { 080 return SQLUtil.getIdentifierNormalName(ModelBindingManager.getGlobalVendor(), name.substring(0, index), 081 ESQLDataObjectType.dotTable) + name.substring(index); 082 } else { 083 return name; 084 } 085 } 086 if (name.endsWith(")") && name.indexOf("(") != -1) { 087 return SQLUtil.getIdentifierNormalName(ModelBindingManager.getGlobalVendor(), 088 name.substring(0, name.lastIndexOf("(")), ESQLDataObjectType.dotTable) 089 + name.substring(name.lastIndexOf("(")); 090 } 091 return SQLUtil.getIdentifierNormalName(ModelBindingManager.getGlobalVendor(), name, 092 ESQLDataObjectType.dotTable); 093 } 094 095 public static String getIdentifierNormalFunctionName(String name) { 096 return SQLUtil.getIdentifierNormalName(ModelBindingManager.getGlobalVendor(), name, 097 ESQLDataObjectType.dotFunction); 098 } 099 100 public static String getIdentifierNormalName(String name, ESQLDataObjectType sqlDataObjectType) { 101 return SQLUtil.getIdentifierNormalName(ModelBindingManager.getGlobalVendor(), name, sqlDataObjectType); 102 } 103 104 public static String getColumnName(TObjectName column) { 105 if (column == null || column.toString() == null) { 106 return null; 107 } 108 String name = column.getColumnNameOnly(); 109 if (name == null || "".equals(name.trim())) { 110 return getIdentifierNormalColumnName(column.toString().trim()); 111 } else 112 return getIdentifierNormalColumnName(name.trim()); 113 } 114 115 public static String getColumnName(String column) { 116 if (column == null) { 117 return null; 118 } 119 String name = column.substring(column.lastIndexOf(".") + 1); 120 if (name == null || "".equals(name.trim())) { 121 return DlineageUtil.getIdentifierNormalColumnName(column.toString().trim()); 122 } else 123 return DlineageUtil.getIdentifierNormalColumnName(name.trim()); 124 } 125 126 public static boolean isTempTable(Table tableModel, EDbVendor vendor) { 127 if (SubType.temp_table == tableModel.getSubType()) { 128 return true; 129 } 130 switch (vendor) { 131 case dbvmssql: 132 case dbvazuresql: 133 return tableModel.getName().startsWith("#") && !tableModel.getName().startsWith("##"); 134 default: 135 return false; 136 } 137 } 138 139 public static String getTableFullName(String tableName) { 140 if (ModelBindingManager.get() != null && ModelBindingManager.get().isDblinkTable(tableName)) { 141 return tableName; 142 } 143 144 if(tableName == null){ 145 return null; 146 } 147 148 if (tableName.startsWith("`") && tableName.endsWith("`") && tableName.indexOf(".") != -1 149 && ModelBindingManager.getGlobalOption().getVendor() == EDbVendor.dbvbigquery) { 150 tableName = SQLUtil.trimColumnStringQuote(tableName); 151 } 152 List<String> segments = SQLUtil.parseNames(tableName); 153 if (segments.size() == 1) { 154 StringBuffer buffer = new StringBuffer(); 155 if (ModelBindingManager.getGlobalDatabase() != null) { 156 buffer.append(ModelBindingManager.getGlobalDatabase()).append("."); 157 } 158 if (ModelBindingManager.getGlobalSchema() != null) { 159 buffer.append(ModelBindingManager.getGlobalSchema()).append("."); 160 } 161 buffer.append(tableName); 162 return getIdentifierNormalTableName(buffer.toString()); 163 } else if (segments.size() == 2) { 164 if (ModelBindingManager.getGlobalDatabase() != null) { 165 return getIdentifierNormalTableName(ModelBindingManager.getGlobalDatabase() + "." + tableName); 166 } else { 167 return getIdentifierNormalTableName(tableName); 168 } 169 } else { 170 if ((ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql 171 || ModelBindingManager.getGlobalVendor() == EDbVendor.dbvazuresql) && tableName.indexOf("..") != -1) { 172 if (ModelBindingManager.getGlobalSchema() != null) { 173 return getIdentifierNormalTableName( 174 tableName.replace("..", "." + ModelBindingManager.getGlobalSchema() + ".")); 175 } else if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql 176 || ModelBindingManager.getGlobalVendor() == EDbVendor.dbvazuresql) { 177 return getIdentifierNormalTableName(tableName.replace("..", ".dbo.")); 178 } else { 179 return getIdentifierNormalTableName(tableName); 180 } 181 } else { 182 return getIdentifierNormalTableName(tableName); 183 } 184 } 185 } 186 187 188 189 public static String getSimpleTableName(String tableName) { 190 if (tableName.startsWith("`") && tableName.endsWith("`") && tableName.indexOf(".") != -1 191 && ModelBindingManager.getGlobalOption().getVendor() == EDbVendor.dbvbigquery) { 192 tableName = SQLUtil.trimColumnStringQuote(tableName); 193 } 194 List<String> segments = SQLUtil.parseNames(tableName); 195 return segments.get(segments.size()-1); 196 } 197 198 public static String getColumnNameOnly(String columnName) { 199 if (columnName.startsWith("`") && columnName.endsWith("`") && columnName.indexOf(".") != -1 200 && ModelBindingManager.getGlobalOption().getVendor() == EDbVendor.dbvbigquery) { 201 columnName = SQLUtil.trimColumnStringQuote(columnName); 202 } 203 List<String> segments = SQLUtil.parseNames(columnName); 204 return segments.get(segments.size()-1); 205 } 206 207 public static String getTableSchema(String tableName) { 208 EDbVendor vendor = ModelBindingManager.getGlobalOption().getVendor(); 209 boolean supportSchema = TSQLEnv.supportSchema(vendor); 210 211 if (tableName.startsWith("`") && tableName.endsWith("`") && tableName.indexOf(".") != -1 212 && ModelBindingManager.getGlobalOption().getVendor() == EDbVendor.dbvbigquery) { 213 tableName = SQLUtil.trimColumnStringQuote(tableName); 214 } 215 List<String> segments = SQLUtil.parseNames(tableName); 216 if (segments.size() == 1) { 217 if (supportSchema && ModelBindingManager.getGlobalSchema() != null) { 218 return ModelBindingManager.getGlobalSchema(); 219 } 220 } else if (segments.size() == 2) { 221 if(supportSchema) { 222 return segments.get(0); 223 } 224 } else { 225 if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql && tableName.indexOf("..") != -1) { 226 if (ModelBindingManager.getGlobalSchema() != null) { 227 return ModelBindingManager.getGlobalSchema(); 228 } else if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql) { 229 return "dbo"; 230 } 231 } else { 232 if(supportSchema) { 233 return segments.get(segments.size() - 2); 234 } 235 } 236 } 237 return null; 238 } 239 240 public static String getTableServer(String tableName) { 241 EDbVendor vendor = ModelBindingManager.getGlobalOption().getVendor(); 242 boolean supportCatalog = TSQLEnv.supportCatalog(vendor); 243 boolean supportSchema = TSQLEnv.supportSchema(vendor); 244 245 if (tableName.startsWith("`") && tableName.endsWith("`") && tableName.indexOf(".") != -1 246 && ModelBindingManager.getGlobalOption().getVendor() == EDbVendor.dbvbigquery) { 247 tableName = SQLUtil.trimColumnStringQuote(tableName); 248 } 249 List<String> segments = SQLUtil.parseNames(tableName); 250 if (segments.size() <= 2) { 251 return ModelBindingManager.getGlobalServer(); 252 } else if (segments.size() == 3) { 253 if(supportCatalog && supportSchema) { 254 return ModelBindingManager.getGlobalServer(); 255 } else { 256 return segments.get(0); 257 } 258 } else { 259 if(supportCatalog && supportSchema) { 260 return segments.get(segments.size() - 4); 261 } else { 262 return segments.get(segments.size() - 3); 263 } 264 } 265 } 266 267 public static String getTableDatabase(String tableName) { 268 EDbVendor vendor = ModelBindingManager.getGlobalOption().getVendor(); 269 boolean supportCatalog = TSQLEnv.supportCatalog(vendor); 270 boolean supportSchema = TSQLEnv.supportSchema(vendor); 271 272 if (tableName.startsWith("`") && tableName.endsWith("`") && tableName.indexOf(".") != -1 273 && ModelBindingManager.getGlobalOption().getVendor() == EDbVendor.dbvbigquery) { 274 tableName = SQLUtil.trimColumnStringQuote(tableName); 275 } 276 List<String> segments = SQLUtil.parseNames(tableName); 277 if (segments.size() == 1) { 278 if (supportCatalog && ModelBindingManager.getGlobalDatabase() != null) { 279 return ModelBindingManager.getGlobalDatabase(); 280 } 281 } else if (segments.size() == 2) { 282 if(supportCatalog && supportSchema) { 283 if (ModelBindingManager.getGlobalDatabase() != null) { 284 return ModelBindingManager.getGlobalDatabase(); 285 } 286 } else { 287 if (supportCatalog) { 288 return segments.get(0); 289 } 290 } 291 } else { 292 if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql && tableName.indexOf("..") != -1) { 293 String fullName = tableName; 294 if (ModelBindingManager.getGlobalSchema() != null) { 295 fullName = getIdentifierNormalTableName( 296 tableName.replace("..", "." + ModelBindingManager.getGlobalSchema() + ".")); 297 } else if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql) { 298 fullName = getIdentifierNormalTableName(tableName.replace("..", ".dbo.")); 299 } else { 300 fullName = getIdentifierNormalTableName(tableName); 301 } 302 return getTableDatabase(fullName); 303 } else { 304 if(supportCatalog && supportSchema) { 305 return segments.get(segments.size() - 3); 306 } 307 else if(supportCatalog){ 308 return segments.get(segments.size() - 2); 309 } 310 } 311 } 312 return null; 313 } 314 315 public static String getTableFullNameWithDefaultSchema(String tableName) { 316 EDbVendor vendor = ModelBindingManager.getGlobalOption().getVendor(); 317 boolean supportCatalog = TSQLEnv.supportCatalog(vendor); 318 boolean supportSchema = TSQLEnv.supportSchema(vendor); 319 320 if (tableName.startsWith("`") && tableName.endsWith("`") && tableName.indexOf(".") != -1 321 && ModelBindingManager.getGlobalOption().getVendor() == EDbVendor.dbvbigquery) { 322 tableName = SQLUtil.trimColumnStringQuote(tableName); 323 } 324 List<String> segments = SQLUtil.parseNames(tableName); 325 if (segments.size() == 1) { 326 StringBuffer buffer = new StringBuffer(); 327 if (supportCatalog && ModelBindingManager.getGlobalDatabase() != null) { 328 buffer.append(ModelBindingManager.getGlobalDatabase()).append("."); 329 } 330 if (supportSchema && ModelBindingManager.getGlobalSchema() != null) { 331 buffer.append(ModelBindingManager.getGlobalSchema()).append("."); 332 } else if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql) { 333 buffer.append("dbo").append("."); 334 } 335 buffer.append(tableName); 336 return getIdentifierNormalTableName(buffer.toString()); 337 } else if (segments.size() == 2) { 338 if (supportCatalog && supportSchema && ModelBindingManager.getGlobalDatabase() != null) { 339 return getIdentifierNormalTableName(ModelBindingManager.getGlobalDatabase() + "." + tableName); 340 } else { 341 return getIdentifierNormalTableName(tableName); 342 } 343 } else { 344 if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql && tableName.indexOf("..") != -1) { 345 if (ModelBindingManager.getGlobalSchema() != null) { 346 return getIdentifierNormalTableName( 347 tableName.replace("..", "." + ModelBindingManager.getGlobalSchema() + ".")); 348 } else if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql) { 349 return getIdentifierNormalTableName(tableName.replace("..", ".dbo.")); 350 } else { 351 return getIdentifierNormalTableName(tableName); 352 } 353 } else { 354 return getIdentifierNormalTableName(tableName); 355 } 356 } 357 } 358 359 @SuppressWarnings("rawtypes") 360 public static SqlInfo[] convertSQL(File file, String json) { 361 List<SqlInfo> sqlInfos = new ArrayList<SqlInfo>(); 362 try { 363 List sqlContents = (List) JSON.parseObject(json); 364 for (int j = 0; j < sqlContents.size(); j++) { 365 Map sqlContent = (Map) sqlContents.get(j); 366 String sql = (String) sqlContent.get("sql"); 367 String fileName = (String) sqlContent.get("fileName"); 368 String filePath = (String) sqlContent.get("filePath"); 369 if (sql != null && sql.trim().startsWith("{")) { 370 Map queryObject = (Map) JSON.parseObject(sql); 371 List querys = (List) queryObject.get("queries"); 372 if (querys != null) { 373 for (int i = 0; i < querys.size(); i++) { 374 Map object = (Map) querys.get(i); 375 SqlInfo info = new SqlInfo(); 376 info.setSql(JSON.toJSONString(object)); 377 info.setFileName(fileName); 378 info.setFilePath(filePath); 379 info.setOriginIndex(i); 380 sqlInfos.add(info); 381 } 382 } else { 383 SqlInfo info = new SqlInfo(); 384 info.setSql(JSON.toJSONString(queryObject)); 385 info.setFileName(fileName); 386 info.setFilePath(filePath); 387 info.setOriginIndex(0); 388 sqlInfos.add(info); 389 } 390 } else if (sql != null) { 391 SqlInfo info = new SqlInfo(); 392 info.setSql(sql); 393 info.setFileName(fileName); 394 info.setFilePath(filePath); 395 info.setOriginIndex(0); 396 sqlInfos.add(info); 397 } 398 } 399 } catch (Exception e) { 400 try { 401 Map queryObject = (Map) JSON.parseObject(json); 402 List querys = (List) queryObject.get("queries"); 403 if (querys != null) { 404 for (int i = 0; i < querys.size(); i++) { 405 Map object = (Map) querys.get(i); 406 SqlInfo info = new SqlInfo(); 407 info.setSql(JSON.toJSONString(object)); 408 if (file != null) { 409 info.setFileName(file.getName()); 410 info.setFilePath(file.getAbsolutePath()); 411 } 412 info.setOriginIndex(i); 413 sqlInfos.add(info); 414 } 415 } else { 416 SqlInfo info = new SqlInfo(); 417 info.setSql(JSON.toJSONString(queryObject)); 418 if (file != null) { 419 info.setFileName(file.getName()); 420 info.setFilePath(file.getAbsolutePath()); 421 } 422 info.setOriginIndex(0); 423 sqlInfos.add(info); 424 } 425 } catch (Exception e1) { 426 SqlInfo info = new SqlInfo(); 427 info.setSql(json); 428 if (file != null) { 429 info.setFileName(file.getName()); 430 info.setFilePath(file.getAbsolutePath()); 431 } 432 info.setOriginIndex(0); 433 sqlInfos.add(info); 434 } 435 } 436 return sqlInfos.toArray(new SqlInfo[0]); 437 } 438 439 440 public static String getQualifiedTableName(table table) { 441 boolean supportCatalog = TSQLEnv.supportCatalog(ModelBindingManager.getGlobalVendor()); 442 boolean supportSchema = TSQLEnv.supportSchema(ModelBindingManager.getGlobalVendor()); 443 StringBuilder buffer = new StringBuilder(); 444 if (supportCatalog && supportSchema) { 445 if (!SQLUtil.isEmpty(table.getDatabase())) { 446 if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvoracle 447 && SubType.dblink.name().equals(table.getSubType())) { 448 //dblink doesn't set database 449 } else { 450 buffer.append(table.getDatabase()); 451 } 452 } 453 if (!SQLUtil.isEmpty(table.getSchema())) { 454 if (buffer.length() > 0) { 455 buffer.append("."); 456 } 457 buffer.append(table.getSchema()); 458 } else { 459 if (buffer.length() > 0) { 460 buffer.append("."); 461 if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql) { 462 buffer.append("dbo"); 463 } else { 464 buffer.append(TSQLEnv.DEFAULT_SCHEMA_NAME); 465 } 466 } 467 } 468 if (buffer.length() > 0) { 469 buffer.append("."); 470 } 471 buffer.append(table.getTableNameOnly()); 472 } 473 else if(supportCatalog) { 474 if (!SQLUtil.isEmpty(table.getDatabase())) { 475 buffer.append(table.getDatabase()); 476 } 477 if (buffer.length() > 0) { 478 buffer.append("."); 479 } 480 buffer.append(table.getTableNameOnly()); 481 } 482 else if(supportSchema) { 483 if (!SQLUtil.isEmpty(table.getSchema())) { 484 buffer.append(table.getSchema()); 485 } 486 if (buffer.length() > 0) { 487 buffer.append("."); 488 } 489 buffer.append(table.getTableNameOnly()); 490 } 491 if (SubType.dblink.name().equals(table.getSubType())) { 492 buffer.append("@").append(table.getDatabase()); 493 } 494 return buffer.toString(); 495 } 496 497 public static TCustomSqlStatement getTopStmt(TCustomSqlStatement stmt) { 498 if (ModelBindingManager.getGlobalOption() != null && ModelBindingManager.getGlobalOption().getAnalyzeMode() == AnalyzeMode.crud) { 499 TCustomSqlStatement parent = stmt.getParentStmt(); 500 if (parent == null || parent instanceof TPlsqlCreatePackage 501 || parent instanceof TStoredProcedureSqlStatement || parent instanceof TCommonBlock) 502 return stmt; 503 return getTopStmt(parent); 504 } else { 505 TCustomSqlStatement parent = stmt.getParentStmt(); 506 if (parent == null || parent instanceof TPlsqlCreatePackage) 507 return stmt; 508 return getTopStmt(parent); 509 } 510 } 511 512 public static boolean isQuote(String column) { 513 return (column.startsWith("\"") && column.endsWith("\"")) || (column.startsWith("'") && column.endsWith("'")) 514 || (column.startsWith("[") && column.endsWith("]")) || (column.startsWith("`") && column.endsWith("`")); 515 } 516 517 public static String getProcedureNameWithArgs(TStoredProcedureSqlStatement stmt) { 518 StringBuilder buffer = new StringBuilder(); 519 if (stmt.getStoredProcedureName() == null) { 520 return null; 521 } 522 buffer.append(stmt.getStoredProcedureName().toString()); 523 if (stmt.getParameterDeclarations() != null && DlineageUtil.supportFunctionOverride(ModelBindingManager.getGlobalVendor())) { 524 buffer.append("("); 525 TParameterDeclarationList parameters = stmt.getParameterDeclarations(); 526 for (int i = 0; i < parameters.size(); ++i) { 527 TParameterDeclaration parameter = parameters.getParameterDeclarationItem(i); 528 if(parameter.getDataType()!=null) { 529 buffer.append(parameter.getDataType().getDataTypeName()); 530 } 531 if(i<parameters.size()-1) { 532 buffer.append(","); 533 } 534 } 535 buffer.append(")"); 536 } 537 return buffer.toString(); 538 } 539 540 public static String getIdentifierProcedureNameWithArgNum(procedure procedure) { 541 StringBuilder buffer = new StringBuilder(); 542 buffer.append(SQLUtil.trimColumnStringQuote(procedure.getName())); 543 if (procedure.getArguments() != null && procedure.getArguments().size() > 0 && DlineageUtil.supportFunctionOverride(ModelBindingManager.getGlobalVendor())) { 544 buffer.append("("); 545 buffer.append(procedure.getArguments().size()); 546 buffer.append(")"); 547 } 548 return buffer.toString().toUpperCase(); 549 } 550 551 public static String getIdentifierOraclePackageNameWithArgNum(oraclePackage pkg) { 552 StringBuilder buffer = new StringBuilder(); 553 buffer.append(SQLUtil.trimColumnStringQuote(pkg.getName())); 554 if (pkg.getArguments() != null && pkg.getArguments().size() > 0 && DlineageUtil.supportFunctionOverride(ModelBindingManager.getGlobalVendor())) { 555 buffer.append("("); 556 buffer.append(pkg.getArguments().size()); 557 buffer.append(")"); 558 } 559 return buffer.toString().toUpperCase(); 560 } 561 562 public static String getIdentifierFunctionName(table function) { 563 StringBuilder buffer = new StringBuilder(); 564 buffer.append(SQLUtil.trimColumnStringQuote(function.getName())); 565 return buffer.toString().toUpperCase(); 566 } 567 568 public static String getProcedureNameWithArgNum(TStoredProcedureSqlStatement stmt) { 569 StringBuilder buffer = new StringBuilder(); 570 if (stmt.getStoredProcedureName() == null) { 571 return null; 572 } 573 buffer.append(stmt.getStoredProcedureName().toString()); 574 if (stmt.getParameterDeclarations() != null && DlineageUtil.supportFunctionOverride(ModelBindingManager.getGlobalVendor())) { 575 buffer.append("("); 576 buffer.append(stmt.getParameterDeclarations().size()); 577 buffer.append(")"); 578 } 579 return buffer.toString(); 580 } 581 582 public static String getProcedureNameWithInputArgNum(TStoredProcedureSqlStatement stmt) { 583 StringBuilder buffer = new StringBuilder(); 584 if (stmt.getStoredProcedureName() == null) { 585 return null; 586 } 587 buffer.append(stmt.getStoredProcedureName().toString()); 588 if (stmt.getParameterDeclarations() != null && DlineageUtil.supportFunctionOverride(ModelBindingManager.getGlobalVendor())) { 589 buffer.append("("); 590 int count = 0; 591 for (int i = 0; i < stmt.getParameterDeclarations().size(); i++) { 592 if (stmt.getParameterDeclarations().getParameterDeclarationItem(i) 593 .getParameterMode() == EParameterMode.in) { 594 count++; 595 } 596 } 597 if (count == 0) { 598 count = stmt.getParameterDeclarations().size(); 599 } 600 buffer.append(count); 601 buffer.append(")"); 602 } 603 return buffer.toString(); 604 } 605 606 public static String getFunctionNameWithArgNum(TFunctionCall function) { 607 StringBuilder buffer = new StringBuilder(); 608 buffer.append(function.getFunctionName().toString()); 609 if (function.getArgs() != null && DlineageUtil.supportFunctionOverride(ModelBindingManager.getGlobalVendor())) { 610 buffer.append("("); 611 buffer.append(function.getArgs().size()); 612 buffer.append(")"); 613 } 614 return buffer.toString(); 615 } 616 617 public static String getTableSchema(Table tableModel) { 618 StringBuilder buffer = new StringBuilder(); 619 if(tableModel.getDatabase()!=null) { 620 buffer.append(tableModel.getDatabase()); 621 } 622 else { 623 buffer.append(TSQLEnv.DEFAULT_DB_NAME); 624 } 625 buffer.append("."); 626 if(tableModel.getSchema()!=null) { 627 buffer.append(tableModel.getSchema()); 628 } 629 else { 630 buffer.append(TSQLEnv.DEFAULT_SCHEMA_NAME); 631 } 632 return buffer.toString(); 633 } 634 635 public static String getTableSQLEnvKey(Table tableModel) { 636 StringBuilder buffer = new StringBuilder(); 637 if(tableModel.getDatabase()!=null) { 638 buffer.append(tableModel.getDatabase()); 639 } 640 else { 641 buffer.append(TSQLEnv.DEFAULT_DB_NAME); 642 } 643 buffer.append("."); 644 if(tableModel.getSchema()!=null) { 645 buffer.append(tableModel.getSchema()); 646 } 647 else { 648 buffer.append(TSQLEnv.DEFAULT_SCHEMA_NAME); 649 } 650 buffer.append("."); 651 buffer.append(DlineageUtil.getSimpleTableName(tableModel.getName())); 652 return buffer.toString(); 653 } 654 655 public static String getProcedureParentName(TCustomSqlStatement stmt) { 656 if (stmt instanceof TStoredProcedureSqlStatement) { 657 if (((TStoredProcedureSqlStatement) stmt).getStoredProcedureName() != null) { 658 return getOraclePackageName() + ((TStoredProcedureSqlStatement) stmt).getStoredProcedureName().toString(); 659 } 660 } 661 stmt = stmt.getParentStmt(); 662 if (stmt == null) 663 return null; 664 665 if (stmt instanceof TCommonBlock) { 666 if(((TCommonBlock) stmt).getBlockBody().getParentObjectName() instanceof TStoredProcedureSqlStatement) { 667 stmt = (TStoredProcedureSqlStatement)((TCommonBlock) stmt).getBlockBody().getParentObjectName(); 668 } 669 } 670 671 if (stmt instanceof TStoredProcedureSqlStatement) { 672 if (((TStoredProcedureSqlStatement) stmt).getStoredProcedureName() != null) { 673 String procedureName = getOraclePackageName() + ((TStoredProcedureSqlStatement) stmt).getStoredProcedureName().toString(); 674 return getTableFullName(procedureName); 675 } 676 } 677 if (stmt instanceof TTeradataCreateProcedure) { 678 if (((TTeradataCreateProcedure) stmt).getProcedureName() != null) { 679 String procedureName = ((TTeradataCreateProcedure) stmt).getProcedureName().toString(); 680 return getTableFullName(procedureName); 681 } 682 } 683 684 return getProcedureParentName(stmt); 685 } 686 687 private static String getOraclePackageName() { 688 if (ModelBindingManager.getGlobalOraclePackage() != null) { 689 return ModelBindingManager.getGlobalOraclePackage().getName() + "."; 690 } 691 return ""; 692 } 693 694 public static sourceColumn copySourceColumn(sourceColumn oldSourceName) { 695 sourceColumn newSourceColumn = new sourceColumn(); 696 newSourceColumn.setClauseType(oldSourceName.getClauseType()); 697 newSourceColumn.setColumn(oldSourceName.getColumn()); 698 newSourceColumn.setColumn_type(oldSourceName.getColumn_type()); 699 newSourceColumn.setCoordinate(oldSourceName.getCoordinate()); 700 newSourceColumn.setId(oldSourceName.getId()); 701 newSourceColumn.setName(oldSourceName.getName()); 702 newSourceColumn.setParent_alias(oldSourceName.getParent_alias()); 703 newSourceColumn.setParent_id(oldSourceName.getParent_id()); 704 newSourceColumn.setParent_name(oldSourceName.getParent_name()); 705 newSourceColumn.setSource(oldSourceName.getSource()); 706 newSourceColumn.setSource_id(oldSourceName.getSource_id()); 707 newSourceColumn.setSource_name(oldSourceName.getSource_name()); 708 newSourceColumn.setStruct(oldSourceName.isStruct()); 709 newSourceColumn.setType(oldSourceName.getType()); 710 newSourceColumn.setValue(oldSourceName.getValue()); 711 if(oldSourceName.getTransforms()!=null) { 712 newSourceColumn.setTransforms(new LinkedHashSet<transform>()); 713 for(transform transform: oldSourceName.getTransforms()) { 714 newSourceColumn.getTransforms().add(transform); 715 } 716 } 717 if(oldSourceName.getCandidateParents()!=null) { 718 newSourceColumn.setCandidateParents(new LinkedHashSet<candidateTable>()); 719 for(candidateTable candidateTable: oldSourceName.getCandidateParents()) { 720 newSourceColumn.getCandidateParents().add(candidateTable); 721 } 722 } 723 return newSourceColumn; 724 } 725 726 public static boolean supportFunctionOverride(EDbVendor vendor) { 727 switch (vendor) { 728 case dbvpostgresql: 729 case dbvoracle: 730 case dbvdb2: 731 case dbvmysql: 732 case dbvsnowflake: 733 case dbvhana: 734 case dbvgreenplum: 735 case dbvgaussdb: 736 case dbvedb: 737 case dbvdameng: 738 return true; 739 default: 740 return false; 741 } 742 } 743 744 private static final List<String> TERADATA_BUILTIN_FUNCTIONS = Arrays 745 .asList(new String[] { "ACCOUNT", "CURRENT_DATE", "CURRENT_ROLE", "CURRENT_TIME", "CURRENT_TIMESTAMP", 746 "CURRENT_USER", "DATABASE", "DATE", "PROFILE", "ROLE", "SESSION", "TIME", "USER", "SYSDATE", }); 747 748 public static boolean isBuiltInFunctionName(String functionName) { 749 if (functionName == null) 750 return false; 751 try { 752 EDbVendor vendor = ModelBindingManager.getGlobalOption().getVendor(); 753 if (vendor == EDbVendor.dbvteradata) { 754 boolean result = TERADATA_BUILTIN_FUNCTIONS.contains(functionName.toUpperCase()); 755 if (result) { 756 return true; 757 } 758 } 759 760 List<String> versions = functionChecker.getAvailableDbVersions(vendor); 761 if (versions != null && versions.size() > 0) { 762 for (int i = 0; i < versions.size(); i++) { 763 boolean result = functionChecker.isBuiltInFunction(functionName.toUpperCase(), 764 vendor, versions.get(i)); 765 if (result) { 766 return result; 767 } 768 } 769 770 // boolean result = 771 // TERADATA_BUILTIN_FUNCTIONS.contains(object.toString()); 772 // if (result) { 773 // return true; 774 // } 775 } 776 } catch (Exception e) { 777 } 778 779 return false; 780 } 781 782 public static boolean isKeyword(String objectName) { 783 if (objectName == null) 784 return false; 785 try { 786 EDbVendor vendor = ModelBindingManager.getGlobalOption().getVendor(); 787 788 List<String> versions = keywordChecker.getAvailableDbVersions(vendor); 789 if (versions != null && versions.size() > 0) { 790 for (int i = 0; i < versions.size(); i++) { 791 List<String> segments = SQLUtil.parseNames(objectName); 792 boolean result = keywordChecker.isKeyword(segments.get(segments.size() - 1), 793 vendor, versions.get(i), false); 794 if (result) { 795 return result; 796 } 797 } 798 } 799 } catch (Exception e) { 800 } 801 802 return false; 803 } 804 805 public static TSelectSqlStatement getLeftStmt(TSelectSqlStatement stmt) { 806 TSelectSqlStatement current = stmt.getLeftStmt(); 807 if (current == null) return null; 808 while (current.getLeftStmt() != null) { 809 current = current.getLeftStmt(); 810 } 811 return current; 812 } 813 814 public static String stripQuotesFromQualifiedName(String qualifiedName) { 815 if (SQLUtil.isEmpty(qualifiedName)) { 816 return qualifiedName; 817 } 818 819 List<String> segments = SQLUtil.parseNames(qualifiedName); 820 StringBuilder sb = new StringBuilder(); 821 for (int i = 0; i < segments.size(); i++) { 822 if (i > 0) { 823 sb.append('.'); 824 } 825 String seg = segments.get(i); 826 sb.append(TBaseType.getTextWithoutQuoted(seg)); 827 } 828 return sb.toString(); 829 } 830 831 public static boolean isProcedureExcluded(String fullName) { 832 if (SQLUtil.isEmpty(fullName)) { 833 return false; 834 } 835 836 Option option = ModelBindingManager.getGlobalOption(); 837 if (option == null) { 838 return false; 839 } 840 841 Set<String> excludedNames = option.getExcludedProcedureNames(); 842 Set<String> excludedPatterns = option.getExcludedProcedurePatterns(); 843 844 if ((excludedNames == null || excludedNames.isEmpty()) && 845 (excludedPatterns == null || excludedPatterns.isEmpty())) { 846 return false; 847 } 848 849 if (excludedNames != null) { 850 for (String excludedName : excludedNames) { 851 if (DlineageUtil.compareIdentifier(fullName, excludedName, ESQLDataObjectType.dotFunction)) { 852 return true; 853 } 854 } 855 } 856 857 if (excludedPatterns != null && !excludedPatterns.isEmpty()) { 858 // Generate the qualified-name and all of its trailing segment-suffixes so a 859 // schema-qualified pattern can match a more-qualified name. e.g. the pattern 860 // "SCHEM.*" matches the Snowflake procedure "DB.SCHEM.PROC" through the suffix 861 // "SCHEM.PROC", and "PUBLIC.*" matches "COVID19.PUBLIC.INSERT_CDC_DATA". 862 // Segments are parsed with quote-awareness so dots inside a quoted identifier 863 // (e.g. "SCHEMA"."PROC.WITH.DOTS") are not split. 864 List<String> candidates = buildQualifiedNameSuffixes(fullName); 865 for (String pattern : excludedPatterns) { 866 if (SQLUtil.isEmpty(pattern)) { 867 continue; 868 } 869 String normalizedPattern = stripQuotesFromQualifiedName(pattern); 870 StringBuilder regexBuilder = new StringBuilder(); 871 for (char c : normalizedPattern.toCharArray()) { 872 switch (c) { 873 case '.': 874 regexBuilder.append("\\."); 875 break; 876 case '*': 877 regexBuilder.append(".*"); 878 break; 879 case '?': 880 regexBuilder.append("."); 881 break; 882 case '(': case ')': case '[': case ']': case '{': case '}': 883 case '|': case '^': case '$': case '+': case '\\': 884 regexBuilder.append("\\").append(c); 885 break; 886 default: 887 regexBuilder.append(c); 888 } 889 } 890 String regex = "(?i)^" + regexBuilder.toString() + "$"; 891 for (String candidate : candidates) { 892 if (candidate.matches(regex)) { 893 return true; 894 } 895 } 896 } 897 } 898 899 return false; 900 } 901 902 /** 903 * Builds the quote-stripped qualified name and each of its trailing segment-suffixes, 904 * longest first. For {@code "DB"."SCHEM"."PROC"} this yields 905 * {@code [DB.SCHEM.PROC, SCHEM.PROC, PROC]}. Used by procedure-exclusion pattern 906 * matching so a schema-level pattern matches a database-qualified name. 907 */ 908 private static List<String> buildQualifiedNameSuffixes(String fullName) { 909 List<String> suffixes = new ArrayList<String>(); 910 List<String> segments = SQLUtil.parseNames(fullName); 911 if (segments == null || segments.isEmpty()) { 912 suffixes.add(stripQuotesFromQualifiedName(fullName)); 913 return suffixes; 914 } 915 List<String> stripped = new ArrayList<String>(segments.size()); 916 for (String seg : segments) { 917 stripped.add(TBaseType.getTextWithoutQuoted(seg)); 918 } 919 for (int i = 0; i < stripped.size(); i++) { 920 StringBuilder sb = new StringBuilder(); 921 for (int j = i; j < stripped.size(); j++) { 922 if (j > i) { 923 sb.append('.'); 924 } 925 sb.append(stripped.get(j)); 926 } 927 suffixes.add(sb.toString()); 928 } 929 return suffixes; 930 } 931}