001package gudusoft.gsqlparser.resolver; 002 003import gudusoft.gsqlparser.*; 004import gudusoft.gsqlparser.compiler.*; 005import gudusoft.gsqlparser.nodes.*; 006import gudusoft.gsqlparser.stmt.*; 007import gudusoft.gsqlparser.stmt.oracle.*; 008import gudusoft.gsqlparser.util.TBuiltFunctionUtil; 009 010import java.util.ArrayList; 011import java.util.Iterator; 012import java.util.Set; 013import java.util.Stack; 014 015/** 016 * TAttributeResolver 的核心职责是为SQL语句中出现的每一个列找到其所属的表。 017 * 018 * 工作原理: 019 * 1. 遍历SQL语句中的所有列引用(TObjectName) 020 * 2. 对每个列,在其可见范围内搜索可能的源表 021 * 3. 建立列和表之间的对应关系 022 * 023 * 列查找规则: 024 * 1. 无表限定列(column): 025 * - 在当前SELECT的FROM子句中所有表中查找 026 * - 如果多个表都有这个列,标记为不明确 027 * 028 * 2. 带表限定列(table.column): 029 * - 在FROM子句中查找指定的表 030 * - 检查该表是否包含指定的列 031 * 032 * 3. 子查询中的列: 033 * - 先在子查询的FROM子句中查找 034 * - 如果未找到,根据子查询类型决定是否查找外层查询 035 * 036 * 查找结果存储: 037 * - 在TObjectName.sourceTable中存储找到的表 038 * - 在TObjectName.candidateTables中存储所有可能的表 039 */ 040public class TAttributeResolver extends TParseTreeVisitor { 041 private TContext globalScope; 042 private TStatementList sqlStatements; 043 private Stack<TScope> scopeStack = new Stack<>(); 044 private final TSQLResolver resolver; 045 private EDbVendor dbVendor = EDbVendor.dbvoracle; 046 047 048 049 public TAttributeResolver(TStatementList sqls, TContext scope, TSQLResolver resolver) { 050 this.globalScope = scope; 051 this.sqlStatements = sqls; 052 this.scopeStack = new Stack<>(); 053 this.resolver = resolver; 054 scopeStack.push(globalScope); 055 if (sqlStatements.size() > 0) { 056 dbVendor = sqlStatements.get(0).dbvendor; 057 } 058 } 059 060 public void resolve() { 061 // System.out.println("==== Start resolving attributes:"); 062// System.out.println("==== SQL Env:"); 063// System.out.println(globalScope.getSqlEnv().toString()); 064 for (int i = 0; i < sqlStatements.size(); i++) { 065 //System.out.println("\n==== Start SQL: "+i); 066 sqlStatements.get(i).acceptChildren(this); 067 } 068 } 069 070 071 072 public void preVisit(TSelectSqlStatement stmt) { 073 // 如果是在 from clause 中出现的 subquery, 它的 parent scope 不能是之前进stack的select语句 074 // SELECT col_1, col_2 075 //FROM ( 076 // select * 077 // FROM table_a 078 // ) a 079 080 // 当上例中 from clause 中的 subquery 入stack时,它的parent scope 不能为整体的那个 select 语句 081 // 需要找到上一层的scope,可能为 global scope, 或者是在 存储过程中的 一个block 082 // 这些上层的 scope可以用来查找是否有 variable 等 symbol 和 subquery 中的 某个 identifier 相匹配 083 084 TScope parent = scopeStack.peek(); 085 086// if ((stmt.getLocation() == ESqlClause.join)||(stmt.getLocation() == ESqlClause.elTable) // from clause 中的 sub-query 087// // ||(stmt.isQueryOfCTE()) // cte 中的 sub-query 也不把直接的父级语句作为 parent env 088// ) 089// { 090// // while (( parent != null) && (parent instanceof TStmtScope) && (((TStmtScope)parent).getStmt() instanceof TSelectSqlStatement)){ 091// while (( parent != null) && (parent instanceof TStmtScope) 092// && (!isValidParentScopeForSubQuery(stmt,(TStmtScope)parent ))){ 093// parent = parent.getEnclosingScope(); 094// } 095// } 096 097 while (( parent != null) && (parent instanceof TStmtScope) 098 && (!isValidParentScopeForSubQuery(stmt,(TStmtScope)parent ))){ 099 parent = parent.getEnclosingScope(); 100 } 101 102 if (stmt.isChildOfCombinedQuery()){ 103 // union set 中的 sub-query 直接使用最顶层 select 的父级 enclosing scope 104 if (parent.getEnclosingScope() != null){ 105 // 如果已经是 global scope, 就不再往上找 106 parent = parent.getEnclosingScope(); 107 } 108 109 if (TBaseType.DUMP_RESOLVER_LOG_TO_CONSOLE){ 110 TBaseType.log(String.format("select in union, parent scope is set to: %s",parent.getName()),TLog.DEBUG,stmt.getStartToken()); 111 } 112 113 // System.out.println("select in union, parent scope is set to:"+parent.getName()); 114 } 115 116 TStmtScope selectScope = new TStmtScope(parent, stmt); 117 scopeStack.push(selectScope); 118 attributeCount = 0; 119 } 120 121 boolean isValidParentScopeForSubQuery(TSelectSqlStatement subquery, TStmtScope scope){ 122 if (!(scope.getStmt() instanceof TSelectSqlStatement)) return true; // 所有非 select 语句都可以是 subquery 的 parent scope 123 if (insidePivotedTable) return false; 124 125 TSelectSqlStatement select = (TSelectSqlStatement)scope.getStmt(); 126// if (subquery.isSubQueryInFromClauseCanUseParentSelectAsEnclosingScope()) return true; 127// 128// return ! ( 129// queryInFromClauseOfSelect(subquery,select )||(queryInsideCTEOfSelect(subquery,select)) 130// ); 131 132 // cte subquery 的上层 select 不能作为 cte subquery 的父层 133 return !queryInsideCTEOfSelect(subquery,select); 134 } 135 136 boolean queryInsideCTEOfSelect(TSelectSqlStatement subquery, TSelectSqlStatement whole){ 137 // 判断一个子查询是否在当前查询的cte中 138 if (whole.getCteList() == null) return false; 139 140 if (whole.getCteList().getStartToken()== null) return false; 141 TSourceToken cteStartToken = whole.getCteList().getStartToken(); 142 if (whole.getCteList().getEndToken() == null) return false; 143 TSourceToken cteEndToken = whole.getCteList().getEndToken(); 144 145 TSourceToken startToken = subquery.getStartToken(); 146 if (startToken == null) return false; 147 if (startToken.lineNo < cteStartToken.lineNo) return false; 148 if ((startToken.lineNo == cteStartToken.lineNo) && (startToken.columnNo < cteStartToken.columnNo)) return false; 149 150 TSourceToken endToken = subquery.getEndToken(); 151 if (endToken.lineNo > cteEndToken.lineNo) return false; 152 if ((endToken.lineNo == cteEndToken.lineNo) && (endToken.columnNo>cteEndToken.columnNo)) return false; 153 154 return true; 155 } 156 157 158 public void postVisit(TSelectSqlStatement stmt) { 159 scopeStack.pop(); 160 removeResolvedOrphanColumns(stmt); 161 } 162 163 public void preVisit(TMergeSqlStatement stmt) { 164 TStmtScope mergeScope = new TStmtScope(scopeStack.peek(),stmt); 165 scopeStack.push(mergeScope); 166 attributeCount = 0; 167 } 168 169 public void postVisit(TMergeSqlStatement stmt) { 170 scopeStack.pop(); 171 } 172 173 public void preVisit(TDeleteSqlStatement stmt) { 174 TStmtScope deleteScope = new TStmtScope(scopeStack.peek(),stmt); 175 scopeStack.push(deleteScope); 176 attributeCount = 0; 177 } 178 179 public void postVisit(TDeleteSqlStatement stmt) { 180 scopeStack.pop(); 181 } 182 183 public void preVisit(TUpdateSqlStatement stmt) { 184 TStmtScope updateScope = new TStmtScope(scopeStack.peek(),stmt); 185 scopeStack.push(updateScope); 186 attributeCount = 0; 187 } 188 189 public void postVisit(TUpdateSqlStatement stmt) { 190 scopeStack.pop(); 191 } 192 193 public void preVisit(TInsertSqlStatement stmt) { 194 TStmtScope insertScope = new TStmtScope(scopeStack.peek(),stmt); 195 scopeStack.push(insertScope); 196 attributeCount = 0; 197 } 198 199 public void postVisit(TInsertSqlStatement stmt) { 200 scopeStack.pop(); 201 } 202 203 public void preVisit(TCreateTableSqlStatement stmt) { 204 // create table stmt 不要入栈作为 scope,否则 205 206// TStmtScope selectScope = new TStmtScope(scopeStack.peek(),stmt); 207// scopeStack.push(selectScope); 208 attributeCount = 0; 209 } 210 211 public void postVisit(TCreateTableSqlStatement stmt) { 212 //scopeStack.pop(); 213 } 214 215 int attributeCount = 0; 216 217 boolean supportedStmtScope(TScope scope){ 218 return ((scope instanceof TStmtScope) 219 ||(scope instanceof TDeleteStmtScope) 220 || (scope instanceof TUpdateStmtScope)); 221 } 222 223 boolean supportedStmt(TCustomSqlStatement stmt){ 224 return (stmt.sqlstatementtype == ESqlStatementType.sstselect) 225 ||(stmt.sqlstatementtype == ESqlStatementType.sstdelete) 226 ||(stmt.sqlstatementtype == ESqlStatementType.sstupdate); 227 228 } 229 230 private boolean insidePivotedTable = false; 231 public void preVisit(TPivotedTable node){ 232 insidePivotedTable = true; 233 } 234 public void postVisit(TPivotedTable node){ 235 insidePivotedTable = false; 236 } 237 238 private boolean insideCrossApplyJoinExpr = false; 239 public void preVisit(TJoinExpr node){ 240 insideCrossApplyJoinExpr = node.getJointype() == EJoinType.crossapply; 241 } 242 243 public void postVisit(TJoinExpr node){ 244 insideCrossApplyJoinExpr = false; 245 } 246 247 248 boolean tmpB; 249 public void preVisit(TPivotClause node){ 250 251 TStmtScope current = (TStmtScope)scopeStack.peek(); 252 // 保留原来的状态,在post时进行恢复 253 tmpB = current.isAllowToSearchInUpLevel(); 254 255 TTable table=null; 256 switch (current.getStmt().sqlstatementtype){ 257 case sstselect: 258 TSelectSqlStatement selectSqlStatement = (TSelectSqlStatement)(current.getStmt()); 259 table = selectSqlStatement.getTables().getTable(0); 260 break; 261 case sstupdate: 262 TUpdateSqlStatement updateSqlStatement = (TUpdateSqlStatement)(current.getStmt()); 263 for(TTable t:updateSqlStatement.getRelations()){ 264 // 获取update语句中from clause中的第一个table 265 if (t.getEffectType() == ETableEffectType.tetSelect){ 266 table = t; 267 break; 268 } 269 } 270 break; 271 } 272 273 if (table != null){ 274 //onlySearchThoseAttributes.addAll(table.getAttributes()); 275 276 TAttributeNode.addAllNodesToList(table.getAttributes(), onlySearchThoseAttributes); 277 if (TBaseType.DUMP_RESOLVER_LOG_TO_CONSOLE){ 278 TBaseType.log(String.format("Pivot clause search attributes derived from table: %s",table.getDisplayName()),TLog.DEBUG,node.getStartToken()); 279 } 280 } 281 282 for(TAttributeNode node1:onlySearchThoseAttributes){ 283 if (TBaseType.DUMP_RESOLVER_LOG_TO_CONSOLE){ 284 TBaseType.log(String.format("\tAttributes: %s",node1.getName()),TLog.DEBUG); 285 } 286 } 287 288 current.setSourceAttributes(onlySearchThoseAttributes); 289 current.setAllowToSearchInUpLevel(false); 290 } 291 public void postVisit(TPivotClause node){ 292 onlySearchThoseAttributes.clear(); 293 294 TStmtScope current = (TStmtScope)scopeStack.peek(); 295 // 恢复原来的状态 296 current.setSourceAttributes(null); 297 current.setAllowToSearchInUpLevel(tmpB); 298 } 299 300 public void preVisit(TMergeInsertClause node){ 301 302 TStmtScope current = (TStmtScope)scopeStack.peek(); 303 // 保留原来的状态,在post时进行恢复 304 tmpB = current.isAllowToSearchInUpLevel(); 305 306 TMergeSqlStatement mergeSqlStatement = (TMergeSqlStatement)(current.getStmt()); 307 308 TTable table = mergeSqlStatement.getUsingTable(); 309 onlySearchThoseAttributes.clear(); 310 //onlySearchThoseAttributes.addAll(table.getAttributes()); 311 312 TAttributeNode.addAllNodesToList(table.getAttributes(), onlySearchThoseAttributes); 313 314 if (TBaseType.DUMP_RESOLVER_LOG_TO_CONSOLE){ 315 TBaseType.log(String.format("MergeInsert clause search attributes derived from using table: %s",table.getDisplayName()),TLog.DEBUG,node.getStartToken()); 316 for(TAttributeNode node1:onlySearchThoseAttributes){ 317 TBaseType.log(String.format("\tAttributes: %s",node1.getName()),TLog.DEBUG); 318 } 319 } 320 321 current.setSourceAttributes(onlySearchThoseAttributes); 322 current.setAllowToSearchInUpLevel(false); 323 } 324 public void postVisit(TMergeInsertClause node){ 325 onlySearchThoseAttributes.clear(); 326 327 TStmtScope current = (TStmtScope)scopeStack.peek(); 328 // 恢复原来的状态 329 current.setSourceAttributes(null); 330 current.setAllowToSearchInUpLevel(tmpB); 331 } 332 333 public void preVisit(TObjectName attribute){ 334 if (isValidatedInOldAlgorithm(attribute)) return; 335 if (isMarkedAsNotAColumn(attribute)){ 336 // 在新算法中加入的校验,如果判断不是一个 column(一般为函数参数中有特别含义的关键字) 337 // 可以从原来的 stmt 的 OrphanColumns 列表中移除,以提高准确性 338 if ((scopeStack.peek() instanceof TStmtScope)) { 339 TStmtScope current = (TStmtScope)scopeStack.peek(); 340 TCustomSqlStatement stmt = current.getStmt(); 341 if (stmt.getOrphanColumns().removeElement(attribute)){ 342 if (TBaseType.DUMP_RESOLVER_LOG_TO_CONSOLE){ 343 TBaseType.log(String.format("Remove fake column <%s> find in old algorithm",attribute.toString()),TLog.WARNING,attribute); 344 } 345 } 346 } 347 return; 348 } 349 350 // check Oracle function in package 351 352 if (isColumn(attribute)){ 353 if (!(scopeStack.peek() instanceof TStmtScope)) return; 354 TStmtScope current = (TStmtScope)scopeStack.peek(); 355 // reset temporary status values 356 attribute.searchLevel = 0; 357 // remove this line since v3.0.3.4, to keep candidate tables for column which maybe retrieved later 358 // in order to find out how many candidate tables for this column 359 // https://www.sqlparser.com/bugs/mantisbt/view.php?id=3849 360 361 // attribute.getCandidateTables().clear(); 362 363 attribute.getCandidateAttributeNodes().clear(); 364 365 // if (attribute.getNumberOfPart() > 2){ 366 // TBaseType.log(String.format("Resolve attribute: %s includes %d parts", attribute.toString(), attribute.getNumberOfPart()), TLog.DEBUG, attribute); 367 // for(int i=0;i<current.getStmt().getTables().size();i++){ 368 // TBaseType.log(String.format("\tTable: %s", current.getStmt().getTables().getTable(i).getDisplayName()), TLog.DEBUG, attribute); 369 // } 370 // } 371 int originalSate = attribute.getValidate_column_status(); 372 current.resolve(attribute); 373 if (attribute.getValidate_column_status() != originalSate){ 374 resolver.reportNewColumns(1); 375 } 376 } 377 } 378 379 public void resolveInThoseRelations(TObjectName attribute, ArrayList<TTable> relations){ 380 381 } 382 383 private ArrayList<TAttributeNode> onlySearchThoseAttributes = new ArrayList<>();// 有些 clause 中的 column 只在指定的 table 中查找 384 385// void collectAttributeFromSubQuery(TTable node, TSelectSqlStatement subquery,String prefix){ 386// 387// int i = 0; 388// if (subquery.getResultColumnList() != null) { 389// for(TResultColumn column: subquery.getResultColumnList()){ 390// if (column.getDisplayName().endsWith("*")){ 391// TObjectName objectName = column.getExpr().getObjectOperand(); 392// for(TAttributeNode attributeNode:objectName.getAttributeNodesDerivedFromFromClause()){ 393// node.getAttributes().add(new TAttributeNode( prefix + attributeNode.getLastPartOfName() ,node,column,i)); 394// } 395// }else{ 396// node.getAttributes().add(new TAttributeNode(prefix +column.getDisplayName(),node,column,i)); 397// } 398// i++; 399// } 400// } 401// } 402 403 404 405 public void postVisit(TTable node) { 406 if (node.isResolved()){ 407 return; 408 } 409 410 switch (node.getTableType()){ 411 case objectname: 412// if (node.isCTEName()){ 413// // 这是一个指向 CTE 的 table ref,根据 CTE 生成该 table ref自己的 attribute 414// for(TAttributeNode node1:node.getCTE().getAttributes()){ 415// node.getAttributes().add(new TAttributeNode( node.getDisplayName() +"."+node1.getLastPartOfName() ,node,node1.getSubLevelResultColumn())); 416// } 417// 418//// for(TAttributeNode node1:node.getAttributes()){ 419//// TBaseType.log(String.format("init cte ref attribute: %s, sub result column is: %s (%d,%d)" 420//// ,node1.getName(),node1.getSubLevelResultColumn().toString(),node1.getSubLevelResultColumn().getStartToken().lineNo, 421//// node1.getSubLevelResultColumn().getStartToken().columnNo) 422//// ,TLog.DEBUG,node.getTableName()); 423//// } 424// } 425 break; 426 case subquery: 427// // 完成 sub-query 类型的 table 的 attributeNode 的收集,以供 attribute resolve 时使用。 428// String prefix = ""; 429// if (node.getAliasClause() != null){ 430// prefix = node.getAliasClause().toString()+"."; 431// } 432// 433// node.initAttributesFromSubquery(node.getSubquery(),prefix); 434// 435// TBaseType. log(String.format("Prepare attributes for table: %s",node.getDisplayName()), TLog.DEBUG,node.getStartToken()); 436// for(TAttributeNode a:node.getAttributes()){ 437// TBaseType.log(String.format("\tAttriubte: %s",a.getName()),TLog.DEBUG,node.getStartToken()); 438// } 439 break; 440 441 } 442 443 // can't use reserved word as table alias 444 if (node.getAliasClause() != null){ 445 if (node.getAliasClause().getAliasName() != null){ 446 if (node.getAliasClause().getAliasName().getStartToken().tokencode == TBaseType.rrw_where){ 447 System.out.println("Where can't be used as table alias"); 448 } 449 } 450 } 451 } 452 453 public void preVisit(TFunctionCall functionCall){ 454 if (functionCall.getArgs() == null) return; 455 Set<Integer> argPos = TBuiltFunctionUtil.argumentsIncludeKeyword(functionCall.dbvendor,functionCall.getFunctionName().toString()); 456 if (argPos == null) return; 457 Iterator<Integer> posIterator = argPos.iterator(); 458 while(posIterator.hasNext()){ 459 int p = posIterator.next(); 460 if (functionCall.getArgs().size() >= p){ 461 markObjectInExprNotAValidColumn(functionCall.getArgs().getExpression(p-1)); 462 } 463 } 464 } 465 466 467 468 public void preVisit(TPlsqlCreatePackage stmt) { 469 TPlsqlCreatePackageScope createPackageScope = new TPlsqlCreatePackageScope(scopeStack.peek(),stmt); 470 scopeStack.push(createPackageScope); 471 // System.out.println("preVisit TPlsqlCreatePackage"); 472 // System.out.println(stmt.getPackageName().toString()); 473 //createPackageScope.addSymbol(new TVariable(stmt.getPackageName(),stmt)); 474 createPackageScope.setLabelName(stmt.getPackageName()); 475 for(TCustomSqlStatement body:stmt.getDeclareStatements()){ 476 if (body instanceof TPlsqlCreateProcedure){ 477 TObjectName routineName = ((TPlsqlCreateProcedure)(body)).getProcedureName(); 478 479 //TObjectName var = TObjectName.createObjectName(stmt.dbvendor,EDbObjectType.variable,new TSourceToken(stmt.getPackageName().toString()+"."+((TPlsqlCreateProcedure)(body)).getProcedureName().toString())); 480 createPackageScope.addSymbol(new TVariable(routineName,stmt)); 481 }else if (body instanceof TPlsqlCreateFunction){ 482 //TObjectName var = TObjectName.createObjectName(stmt.dbvendor,EDbObjectType.variable,new TSourceToken(stmt.getPackageName().toString()+"."+((TPlsqlCreateFunction)(body)).getFunctionName().toString())); 483 TObjectName routineName = ((TPlsqlCreateFunction)(body)).getFunctionName(); 484 createPackageScope.addSymbol(new TVariable(routineName,stmt)); 485 } 486 } 487 488 //createPackageScope.printSymbols(""); 489 490 } 491 492 void removeResolvedOrphanColumns(TCustomSqlStatement stmt){ 493 for(int i=stmt.getOrphanColumns().size()-1;i>=0;i--){ 494 TObjectName objectName = stmt.getOrphanColumns().getObjectName(i); 495 if (objectName.getResolveStatus() == TBaseType.RESOLVED_AND_FOUND){ 496 boolean b = stmt.getOrphanColumns().removeElement(objectName); 497 } 498 } 499 500 for(int i=stmt.getSyntaxHints().size()-1;i>=0;i--){ 501 TSyntaxError hint = stmt.getSyntaxHints().get(i); 502 if (hint.objectName != null && hint.objectName.getResolveStatus() == TBaseType.RESOLVED_AND_FOUND){ 503 stmt.getSyntaxHints().remove(i); 504 } 505 } 506 } 507 508 public void postVisit(TPlsqlCreatePackage stmt) { 509 removeResolvedOrphanColumns(stmt); 510 scopeStack.pop(); 511 } 512 513 public void preVisit(TPlsqlCreateProcedure stmt) { 514 TStmtScope createProcedureScope = new TStmtScope(scopeStack.peek(),stmt); 515 createProcedureScope.setLabelName(stmt.getProcedureName()); 516 scopeStack.push(createProcedureScope); 517 } 518 519 public void postVisit(TPlsqlCreateProcedure stmt) { 520 scopeStack.pop(); 521 } 522 523 public void preVisit(TPlsqlCreateFunction stmt) { 524 TStmtScope createFunctionScope = new TStmtScope(scopeStack.peek(),stmt); 525 createFunctionScope.setLabelName(stmt.getFunctionName()); 526 scopeStack.push(createFunctionScope); 527 } 528 529 public void postVisit(TPlsqlCreateFunction stmt) { 530 scopeStack.pop(); 531 } 532 533 void markObjectInExprNotAValidColumn(TExpression expr){ 534 if (expr.getExpressionType() == EExpressionType.simple_object_name_t){ 535 TObjectName objectName = expr.getObjectOperand(); 536 objectName.setValidate_column_status(TBaseType.MARKED_NOT_A_COLUMN_IN_COLUMN_RESOLVER); 537 expr.setExpressionType(EExpressionType.simple_constant_t); 538 expr.setConstantOperand(new TConstant(ELiteralType.unknownType,objectName.getStartToken())); 539 if (TBaseType.DUMP_RESOLVER_LOG_TO_CONSOLE){ 540 TBaseType.log(String.format("Mark object <%s> as not a column",objectName.toString()),TLog.DEBUG,objectName); 541 } 542 } 543 return; 544 } 545 boolean isValidatedInOldAlgorithm(TObjectName objectName){ 546 return (objectName.getValidate_column_status() == TBaseType.COLUMN_LINKED_TO_TABLE_IN_OLD_ALGORITHM); 547 } 548 549 boolean isMarkedAsNotAColumn(TObjectName objectName){ 550 return (objectName.getValidate_column_status() == TBaseType.MARKED_NOT_A_COLUMN_IN_COLUMN_RESOLVER); 551 } 552 553 boolean isColumn(TObjectName objectName){ 554 return !( 555 (objectName.getDbObjectType() == EDbObjectType.table) 556 ||(objectName.getDbObjectType() == EDbObjectType.alias) 557 ||(objectName.getDbObjectType() == EDbObjectType.attribute) 558 ||(objectName.getDbObjectType() == EDbObjectType.column_alias) 559 ||(objectName.getDbObjectType() == EDbObjectType.constraint) 560 ||(objectName.getDbObjectType() == EDbObjectType.cte) 561 ||(objectName.getDbObjectType() == EDbObjectType.cursor) 562 ||(objectName.getDbObjectType() == EDbObjectType.database) 563 ||(objectName.getDbObjectType() == EDbObjectType.function) 564 ||(objectName.getDbObjectType() == EDbObjectType.index) 565 ||(objectName.getDbObjectType() == EDbObjectType.label) 566 ||(objectName.getDbObjectType() == EDbObjectType.library) 567 ||(objectName.getDbObjectType() == EDbObjectType.materializedView) 568 ||(objectName.getDbObjectType() == EDbObjectType.method) 569 ||(objectName.getDbObjectType() == EDbObjectType.parameter) 570 ||(objectName.getDbObjectType() == EDbObjectType.plsql_package) 571 ||(objectName.getDbObjectType() == EDbObjectType.property) 572 ||(objectName.getDbObjectType() == EDbObjectType.procedure) 573 ||(objectName.getDbObjectType() == EDbObjectType.table_alias) 574 ||(objectName.getDbObjectType() == EDbObjectType.transaction) 575 ||(objectName.getDbObjectType() == EDbObjectType.trigger) 576 ||(objectName.getDbObjectType() == EDbObjectType.sequence) 577 ||(objectName.getDbObjectType() == EDbObjectType.user_defined_type) 578 ||(objectName.getDbObjectType() == EDbObjectType.variable) 579 ||(objectName.getDbObjectType() == EDbObjectType.view) 580 ||(!objectName.isValidColumnName(dbVendor)) 581 ||(objectName.toString().endsWith("*")) 582 ); 583 } 584}