1 /* 2 * Copyright 2015-2018 HuntLabs.cn 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 module hunt.sql.visitor.SchemaStatVisitor; 17 18 19 import std.string; 20 import std.uni; 21 import hunt.collection; 22 import std.array; 23 import hunt.String; 24 import hunt.sql.SQLUtils; 25 import hunt.sql.ast; 26 import hunt.sql.ast.expr; 27 import hunt.sql.ast.statement; 28 import hunt.sql.dialect.mysql.ast.expr.MySqlExpr; 29 import hunt.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter; 30 import hunt.sql.ast.statement.SQLLateralViewTableSource; 31 // import hunt.sql.dialect.odps.ast.OdpsValuesTableSource; 32 // import hunt.sql.dialect.oracle.ast.expr.OracleDbLinkExpr; 33 // import hunt.sql.dialect.oracle.ast.expr.OracleExpr; 34 import hunt.sql.dialect.postgresql.visitor.PGASTVisitorAdapter; 35 import hunt.sql.repository.SchemaObject; 36 import hunt.sql.repository.SchemaRepository; 37 import hunt.sql.stat.TableStat; 38 // import hunt.sql.stat.TableStat.Column; 39 // import hunt.sql.stat.TableStat.Condition; 40 // import hunt.sql.stat.TableStat.Mode; 41 // import hunt.sql.stat.TableStat.Relationship; 42 import hunt.sql.util.FnvHash; 43 import hunt.sql.util.DBType; 44 import hunt.sql.visitor.SQLASTVisitorAdapter; 45 import hunt.Long; 46 import hunt.Boolean; 47 import hunt.sql.visitor.SQLASTVisitor; 48 import hunt.sql.visitor.SQLEvalVisitorUtils; 49 import hunt.sql.visitor.SQLEvalVisitor; 50 import hunt.text; 51 52 public class SchemaStatVisitor : SQLASTVisitorAdapter { 53 54 alias visit = SQLASTVisitorAdapter.visit; 55 alias endVisit = SQLASTVisitorAdapter.endVisit; 56 57 protected SchemaRepository repository; 58 59 protected HashMap!(TableStat.Name, TableStat) tableStats ; 60 protected Map!(Long, TableStat.Column) columns ; 61 protected List!(TableStat.Condition) conditions ; 62 protected Set!(TableStat.Relationship) relationships ; 63 protected List!(TableStat.Column) orderByColumns; 64 protected Set!(TableStat.Column) groupByColumns; 65 protected List!(SQLAggregateExpr) aggregateFunctions; 66 protected List!(SQLMethodInvokeExpr) functions ; 67 68 private List!(Object) parameters; 69 70 private TableStat.Mode mode; 71 72 protected string dbType; 73 74 public this(){ 75 this(cast(string) null); 76 } 77 78 public this(string dbType){ 79 this(new SchemaRepository(dbType), new ArrayList!(Object)()); 80 this.dbType = dbType; 81 } 82 83 public SchemaRepository getRepository() { 84 return repository; 85 } 86 87 public void setRepository(SchemaRepository repository) { 88 this.repository = repository; 89 } 90 91 public this(List!(Object) parameters){ 92 this(cast(string) null, parameters); 93 } 94 95 public this(string dbType, List!(Object) parameters){ 96 this(new SchemaRepository(dbType), parameters); 97 this.parameters = parameters; 98 } 99 100 public this(SchemaRepository repository, List!(Object) parameters){ 101 tableStats = new LinkedHashMap!(TableStat.Name, TableStat); 102 columns = new LinkedHashMap!(Long, TableStat.Column)(); 103 conditions = new ArrayList!(TableStat.Condition)(); 104 relationships = new LinkedHashSet!(TableStat.Relationship)(); 105 orderByColumns = new ArrayList!(TableStat.Column)(); 106 groupByColumns = new LinkedHashSet!(TableStat.Column)(); 107 aggregateFunctions = new ArrayList!(SQLAggregateExpr)(); 108 functions = new ArrayList!(SQLMethodInvokeExpr)(2); 109 110 this.repository = repository; 111 this.parameters = parameters; 112 if (repository !is null) { 113 string dbType = repository.getDbType(); 114 if (dbType !is null && this.dbType is null) { 115 this.dbType = dbType; 116 } 117 } 118 } 119 120 public List!(Object) getParameters() { 121 return parameters; 122 } 123 124 public void setParameters(List!(Object) parameters) { 125 this.parameters = parameters; 126 } 127 128 public TableStat getTableStat(string tableName) { 129 tableName = handleName(tableName); 130 131 TableStat.Name tableNameObj = new TableStat.Name(tableName); 132 TableStat stat = tableStats.get(tableNameObj); 133 if (stat is null) { 134 stat = new TableStat(); 135 tableStats.put(new TableStat.Name(tableName), stat); 136 } 137 return stat; 138 } 139 140 public TableStat getTableStat(SQLName tableName) { 141 string strName = (cast(Object)(tableName)).toString(); 142 long hashCode64 = tableName.hashCode64(); 143 144 if (hashCode64 == FnvHash.Constants.DUAL) { 145 return null; 146 } 147 148 TableStat.Name tableNameObj = new TableStat.Name(strName, hashCode64); 149 TableStat stat = tableStats.get(tableNameObj); 150 if (stat is null) { 151 stat = new TableStat(); 152 tableStats.put(new TableStat.Name(strName, hashCode64), stat); 153 } 154 return stat; 155 } 156 157 protected TableStat.Column addColumn(string tableName, string columnName) { 158 TableStat.Column column = this.getColumn(tableName, columnName); 159 if (column is null && columnName !is null) { 160 column = new TableStat.Column(tableName, columnName); 161 columns.put(new Long(column.hashCode64()), column); 162 } 163 return column; 164 } 165 166 protected TableStat.Column addColumn(SQLName table, string columnName) { 167 string tableName = (cast(Object)(table)).toString(); 168 long tableHashCode64 = table.hashCode64(); 169 170 long basic = tableHashCode64; 171 basic ^= '.'; 172 basic *= FnvHash.PRIME; 173 long columnHashCode64 = FnvHash.hashCode64(basic, columnName); 174 175 TableStat.Column column = this.columns.get(new Long(columnHashCode64)); 176 if (column is null && columnName !is null) { 177 column = new TableStat.Column(tableName, columnName, columnHashCode64); 178 columns.put(new Long(columnHashCode64), column); 179 } 180 return column; 181 } 182 183 private string handleName(string ident) { 184 int len = cast(int)(ident.length); 185 if (charAt(ident, 0) == '[' && charAt(ident, len - 1) == ']') { 186 ident = ident.substring(1, len - 1); 187 } else { 188 bool flag0 = false; 189 bool flag1 = false; 190 bool flag2 = false; 191 bool flag3 = false; 192 for (int i = 0; i < len; ++i) { 193 char ch = charAt(ident, i); 194 if (ch == '\"') { 195 flag0 = true; 196 } else if (ch == '`') { 197 flag1 = true; 198 } else if (ch == ' ') { 199 flag2 = true; 200 } else if (ch == '\'') { 201 flag3 = true; 202 } 203 } 204 if (flag0) { 205 ident = ident.replace("\"", ""); 206 } 207 208 if (flag1) { 209 ident = ident.replace("`", ""); 210 } 211 212 if (flag2) { 213 ident = ident.replace(" ", ""); 214 } 215 216 if (flag3) { 217 ident = ident.replace("'", ""); 218 } 219 } 220 return ident; 221 } 222 223 protected TableStat.Mode getMode() { 224 return mode; 225 } 226 227 protected void setModeOrigin(SQLObject x) { 228 TableStat.Mode originalMode = cast(TableStat.Mode) x.getAttribute("_original_use_mode"); 229 mode = originalMode; 230 } 231 232 protected TableStat.Mode setMode(SQLObject x, const TableStat.Mode mode) { 233 TableStat.Mode oldMode = this.mode; 234 x.putAttribute("_original_use_mode", oldMode); 235 this.mode = cast(TableStat.Mode)mode; 236 return oldMode; 237 } 238 239 private bool visitOrderBy(SQLIdentifierExpr x) { 240 SQLTableSource tableSource = x.getResolvedTableSource(); 241 242 string tableName = null; 243 if (cast(SQLExprTableSource)(tableSource) !is null) { 244 SQLExpr expr = (cast(SQLExprTableSource) tableSource).getExpr(); 245 if (cast(SQLIdentifierExpr)(expr) !is null) { 246 SQLIdentifierExpr table = cast(SQLIdentifierExpr) expr; 247 tableName = table.getName(); 248 } else if (cast(SQLPropertyExpr)(expr) !is null) { 249 SQLPropertyExpr table = cast(SQLPropertyExpr) expr; 250 tableName = (cast(Object)(table)).toString(); 251 } else if (cast(SQLMethodInvokeExpr)(expr) !is null) { 252 SQLMethodInvokeExpr methodInvokeExpr = cast(SQLMethodInvokeExpr) expr; 253 if ("table".equalsIgnoreCase(methodInvokeExpr.getMethodName()) 254 && methodInvokeExpr.getParameters().size() == 1 255 && cast(SQLName)methodInvokeExpr.getParameters().get(0) !is null) { 256 SQLName table = cast(SQLName) methodInvokeExpr.getParameters().get(0); 257 258 if (cast(SQLPropertyExpr)table !is null) { 259 SQLPropertyExpr propertyExpr = cast(SQLPropertyExpr) table; 260 SQLIdentifierExpr owner = cast(SQLIdentifierExpr) propertyExpr.getOwner(); 261 if (propertyExpr.getResolvedTableSource() !is null 262 && (cast(SQLExprTableSource) propertyExpr.getResolvedTableSource()) !is null) { 263 SQLExpr resolveExpr = (cast(SQLExprTableSource) propertyExpr.getResolvedTableSource()).getExpr(); 264 if (cast(SQLName)(resolveExpr) !is null) { 265 tableName = (cast(Object)(resolveExpr)).toString() ~ "." ~ propertyExpr.getName(); 266 } 267 } 268 } 269 270 if (tableName is null) { 271 tableName = (cast(Object)(table)).toString(); 272 } 273 } 274 } 275 } else if (cast(SQLWithSubqueryClause.Entry)(tableSource) !is null) { 276 return false; 277 } else if (cast(SQLSubqueryTableSource)(tableSource) !is null) { 278 SQLSelectQueryBlock queryBlock = (cast(SQLSubqueryTableSource) tableSource).getSelect().getQueryBlock(); 279 if (queryBlock is null) { 280 return false; 281 } 282 283 SQLSelectItem selectItem = queryBlock.findSelectItem(x.nameHashCode64()); 284 if (selectItem is null) { 285 return false; 286 } 287 288 SQLExpr selectItemExpr = selectItem.getExpr(); 289 SQLTableSource columnTableSource = null; 290 if (cast(SQLIdentifierExpr)(selectItemExpr) !is null) { 291 columnTableSource = (cast(SQLIdentifierExpr) selectItemExpr).getResolvedTableSource(); 292 } else if (cast(SQLPropertyExpr)(selectItemExpr) !is null) { 293 columnTableSource = (cast(SQLPropertyExpr) selectItemExpr).getResolvedTableSource(); 294 } 295 296 if (cast(SQLExprTableSource)(columnTableSource) !is null && cast(SQLName) (cast(SQLExprTableSource) columnTableSource).getExpr() !is null) { 297 SQLName tableExpr = cast(SQLName) (cast(SQLExprTableSource) columnTableSource).getExpr(); 298 if (cast(SQLIdentifierExpr)(tableExpr) !is null) { 299 tableName = (cast(SQLIdentifierExpr) tableExpr).normalizedName(); 300 } else if (cast(SQLPropertyExpr)(tableExpr) !is null) { 301 tableName = (cast(SQLPropertyExpr) tableExpr).normalizedName(); 302 } 303 } 304 } else { 305 bool skip = false; 306 for (SQLObject parent = x.getParent();parent !is null;parent = parent.getParent()) { 307 if (cast(SQLSelectQueryBlock)(parent) !is null) { 308 SQLTableSource from = (cast(SQLSelectQueryBlock) parent).getFrom(); 309 310 // if (cast(OdpsValuesTableSource)(from) !is null) { 311 // skip = true; 312 // break; 313 // }//@gxc 314 } else if (cast(SQLSelectQuery)(parent) !is null) { 315 break; 316 } 317 } 318 } 319 320 string identName = x.getName(); 321 if (tableName !is null) { 322 orderByAddColumn(tableName, identName, x); 323 } else { 324 orderByAddColumn("UNKOWN", identName, x); 325 } 326 return false; 327 } 328 329 private bool visitOrderBy(SQLPropertyExpr x) { 330 if (isSubQueryOrParamOrVariant(x)) { 331 return false; 332 } 333 334 string owner = null; 335 336 SQLTableSource tableSource = x.getResolvedTableSource(); 337 if (cast(SQLExprTableSource)(tableSource) !is null) { 338 SQLExpr tableSourceExpr = (cast(SQLExprTableSource) tableSource).getExpr(); 339 if (cast(SQLName)(tableSourceExpr) !is null) { 340 owner = (cast(Object)(tableSourceExpr)).toString(); 341 } 342 } 343 344 if (owner is null && (cast(SQLIdentifierExpr) x.getOwner()).getName() !is null) { 345 owner = (cast(SQLIdentifierExpr) x.getOwner()).getName(); 346 } 347 348 if (owner is null) { 349 return false; 350 } 351 352 if (owner !is null) { 353 orderByAddColumn(owner, x.getName(), x); 354 } 355 356 return false; 357 } 358 359 private void orderByAddColumn(string table, string columnName, SQLObject expr) { 360 TableStat.Column column = new TableStat.Column(table, columnName); 361 362 SQLObject parent = expr.getParent(); 363 if (cast(SQLSelectOrderByItem)(parent) !is null) { 364 SQLOrderingSpecification type = (cast(SQLSelectOrderByItem) parent).getType(); 365 column.getAttributes().put("orderBy.type", cast(Object)type); 366 } 367 368 orderByColumns.add(column); 369 } 370 371 protected class OrderByStatVisitor : SQLASTVisitorAdapter { 372 373 alias visit = SQLASTVisitorAdapter.visit; 374 alias endVisit = SQLASTVisitorAdapter.endVisit; 375 376 private SQLOrderBy orderBy; 377 378 public this(SQLOrderBy orderBy){ 379 this.orderBy = orderBy; 380 foreach(SQLSelectOrderByItem item ; orderBy.getItems()) { 381 item.getExpr().setParent(item); 382 } 383 } 384 385 public SQLOrderBy getOrderBy() { 386 return orderBy; 387 } 388 389 override public bool visit(SQLIdentifierExpr x) { 390 return visitOrderBy(x); 391 } 392 393 override public bool visit(SQLPropertyExpr x) { 394 return visitOrderBy(x); 395 } 396 } 397 398 protected class MySqlOrderByStatVisitor : MySqlASTVisitorAdapter { 399 400 alias visit = MySqlASTVisitorAdapter.visit; 401 alias endVisit = MySqlASTVisitorAdapter.endVisit; 402 403 private SQLOrderBy orderBy; 404 405 public this(SQLOrderBy orderBy){ 406 this.orderBy = orderBy; 407 foreach(SQLSelectOrderByItem item ; orderBy.getItems()) { 408 item.getExpr().setParent(item); 409 } 410 } 411 412 public SQLOrderBy getOrderBy() { 413 return orderBy; 414 } 415 416 override public bool visit(SQLIdentifierExpr x) { 417 return visitOrderBy(x); 418 } 419 420 override public bool visit(SQLPropertyExpr x) { 421 return visitOrderBy(x); 422 } 423 } 424 425 protected class PGOrderByStatVisitor : PGASTVisitorAdapter { 426 427 alias visit = PGASTVisitorAdapter.visit; 428 alias endVisit = PGASTVisitorAdapter.endVisit; 429 430 private SQLOrderBy orderBy; 431 432 public this(SQLOrderBy orderBy){ 433 this.orderBy = orderBy; 434 foreach(SQLSelectOrderByItem item ; orderBy.getItems()) { 435 item.getExpr().setParent(item); 436 } 437 } 438 439 public SQLOrderBy getOrderBy() { 440 return orderBy; 441 } 442 443 override public bool visit(SQLIdentifierExpr x) { 444 return visitOrderBy(x); 445 } 446 447 override public bool visit(SQLPropertyExpr x) { 448 return visitOrderBy(x); 449 } 450 } 451 452 protected class OracleOrderByStatVisitor : PGASTVisitorAdapter { 453 454 alias visit = PGASTVisitorAdapter.visit; 455 alias endVisit = PGASTVisitorAdapter.endVisit; 456 457 private SQLOrderBy orderBy; 458 459 public this(SQLOrderBy orderBy){ 460 this.orderBy = orderBy; 461 foreach(SQLSelectOrderByItem item ; orderBy.getItems()) { 462 item.getExpr().setParent(item); 463 } 464 } 465 466 public SQLOrderBy getOrderBy() { 467 return orderBy; 468 } 469 470 override public bool visit(SQLIdentifierExpr x) { 471 return visitOrderBy(x); 472 } 473 474 override public bool visit(SQLPropertyExpr x) { 475 SQLExpr unwrapped = unwrapExpr(x); 476 if (cast(SQLPropertyExpr)(unwrapped) !is null) { 477 visitOrderBy(cast(SQLPropertyExpr) unwrapped); 478 } else if (cast(SQLIdentifierExpr)(unwrapped) !is null) { 479 visitOrderBy(cast(SQLIdentifierExpr) unwrapped); 480 } 481 return false; 482 } 483 } 484 485 override public bool visit(SQLOrderBy x) { 486 SQLASTVisitor orderByVisitor = createOrderByVisitor(x); 487 488 SQLSelectQueryBlock query = null; 489 if ( cast(SQLSelectQueryBlock) x.getParent() !is null) { 490 query = cast(SQLSelectQueryBlock) x.getParent(); 491 } 492 if (query !is null) { 493 foreach(SQLSelectOrderByItem item ; x.getItems()) { 494 SQLExpr expr = item.getExpr(); 495 if (cast(SQLIntegerExpr)(expr) !is null) { 496 int intValue = (cast(SQLIntegerExpr) expr).getNumber().intValue() - 1; 497 if (intValue < query.getSelectList().size()) { 498 SQLSelectItem selectItem = query.getSelectList().get(intValue); 499 selectItem.getExpr().accept(orderByVisitor); 500 } 501 } else if (cast(MySqlExpr)(expr) !is null /* || cast(OracleExpr)(expr) !is null */) { 502 continue; 503 } 504 } 505 } 506 x.accept(orderByVisitor); 507 508 foreach(SQLSelectOrderByItem orderByItem ; x.getItems()) { 509 statExpr( 510 orderByItem.getExpr()); 511 } 512 513 return false; 514 } 515 516 override public bool visit(SQLOver x) { 517 SQLName of = x.getOf(); 518 SQLOrderBy orderBy = x.getOrderBy(); 519 List!(SQLExpr) partitionBy = x.getPartitionBy(); 520 521 522 if (of is null // skip if of is not null 523 && orderBy !is null) { 524 orderBy.accept(this); 525 } 526 527 if (partitionBy !is null) { 528 foreach(SQLExpr expr ; partitionBy) { 529 expr.accept(this); 530 } 531 } 532 533 return false; 534 } 535 536 protected SQLASTVisitor createOrderByVisitor(SQLOrderBy x) { 537 SQLASTVisitor orderByVisitor; 538 if (DBType.MYSQL.opEquals(dbType)) { 539 orderByVisitor = new MySqlOrderByStatVisitor(x); 540 } else if (DBType.POSTGRESQL.opEquals(dbType)) { 541 orderByVisitor = new PGOrderByStatVisitor(x); 542 } else if (DBType.ORACLE.opEquals(dbType)) { 543 orderByVisitor = new OracleOrderByStatVisitor(x); 544 } else { 545 orderByVisitor = new OrderByStatVisitor(x); 546 } 547 return orderByVisitor; 548 } 549 550 public Set!(TableStat.Relationship) getRelationships() { 551 return relationships; 552 } 553 554 public List!(TableStat.Column) getOrderByColumns() { 555 return orderByColumns; 556 } 557 558 public Set!(TableStat.Column) getGroupByColumns() { 559 return groupByColumns; 560 } 561 562 public List!(TableStat.Condition) getConditions() { 563 return conditions; 564 } 565 566 public List!(SQLAggregateExpr) getAggregateFunctions() { 567 return aggregateFunctions; 568 } 569 570 override public bool visit(SQLBetweenExpr x) { 571 SQLObject parent = x.getParent(); 572 573 SQLExpr test = x.getTestExpr(); 574 SQLExpr begin = x.getBeginExpr(); 575 SQLExpr end = x.getEndExpr(); 576 577 statExpr(test); 578 statExpr(begin); 579 statExpr(end); 580 581 handleCondition(test, "BETWEEN", begin, end); 582 583 return false; 584 } 585 586 override public bool visit(SQLBinaryOpExpr x) { 587 SQLObject parent = x.getParent(); 588 589 if (cast(SQLIfStatement)(parent) !is null) { 590 return true; 591 } 592 593 SQLBinaryOperator op = x.getOperator(); 594 SQLExpr left = x.getLeft(); 595 SQLExpr right = x.getRight(); 596 597 switch (op.name) { 598 case SQLBinaryOperator.Equality.name: 599 case SQLBinaryOperator.NotEqual.name: 600 case SQLBinaryOperator.GreaterThan.name: 601 case SQLBinaryOperator.GreaterThanOrEqual.name: 602 case SQLBinaryOperator.LessThan.name: 603 case SQLBinaryOperator.LessThanOrGreater.name: 604 case SQLBinaryOperator.LessThanOrEqual.name: 605 case SQLBinaryOperator.LessThanOrEqualOrGreaterThan.name: 606 case SQLBinaryOperator.Like.name: 607 case SQLBinaryOperator.NotLike.name: 608 case SQLBinaryOperator.Is.name: 609 case SQLBinaryOperator.IsNot.name: 610 handleCondition(left, x.getOperator().name, right); 611 handleCondition(right, x.getOperator().name, left); 612 613 handleRelationship(left, x.getOperator().name, right); 614 break; 615 case SQLBinaryOperator.BooleanOr.name: { 616 List!(SQLExpr) list = SQLBinaryOpExpr.split(x, op); 617 618 foreach(SQLExpr item ; list) { 619 if (cast(SQLBinaryOpExpr)(item) !is null) { 620 visit(cast(SQLBinaryOpExpr) item); 621 } else { 622 item.accept(this); 623 } 624 } 625 626 return false; 627 } 628 case SQLBinaryOperator.Modulus.name: 629 if (cast(SQLIdentifierExpr)(right) !is null) { 630 long hashCode64 = (cast(SQLIdentifierExpr) right).hashCode64(); 631 if (hashCode64 == FnvHash.Constants.ISOPEN) { 632 left.accept(this); 633 return false; 634 } 635 } 636 break; 637 default: 638 break; 639 } 640 641 statExpr(left); 642 statExpr(right); 643 644 return false; 645 } 646 647 protected void handleRelationship(SQLExpr left, string operator, SQLExpr right) { 648 TableStat.Column leftColumn = getColumn(left); 649 if (leftColumn is null) { 650 return; 651 } 652 653 TableStat.Column rightColumn = getColumn(right); 654 if (rightColumn is null) { 655 return; 656 } 657 658 TableStat.Relationship relationship = new TableStat.Relationship(leftColumn, rightColumn, operator); 659 this.relationships.add(relationship); 660 } 661 662 protected void handleCondition(SQLExpr expr, string operator, List!(SQLExpr) values) { 663 handleCondition(expr, operator, values.toArray()); 664 } 665 666 protected void handleCondition(SQLExpr expr, string operator, SQLExpr[] valueExprs...) { 667 if (cast(SQLCastExpr)(expr) !is null) { 668 expr = (cast(SQLCastExpr) expr).getExpr(); 669 } 670 671 TableStat.Column column = getColumn(expr); 672 if (column is null) { 673 return; 674 } 675 676 TableStat.Condition condition = null; 677 foreach(TableStat.Condition item ; this.getConditions()) { 678 if (item.getColumn().opEquals(column) && item.getOperator() == (operator)) { 679 condition = item; 680 break; 681 } 682 } 683 684 if (condition is null) { 685 condition = new TableStat.Condition(column, operator); 686 this.conditions.add(condition); 687 } 688 689 foreach(SQLExpr item ; valueExprs) { 690 TableStat.Column valueColumn = getColumn(item); 691 if (valueColumn !is null) { 692 continue; 693 } 694 695 Object value; 696 if (cast(SQLMethodInvokeExpr)(item) !is null) { 697 value = (cast(Object)(item)); 698 } else { 699 value = SQLEvalVisitorUtils.eval(dbType, item, parameters, false); 700 if (value == SQLEvalVisitor.EVAL_VALUE_NULL) { 701 value = null; 702 } 703 } 704 705 condition.addValue(value); 706 } 707 } 708 709 public string getDbType() { 710 return dbType; 711 } 712 713 protected TableStat.Column getColumn(SQLExpr expr) { 714 SQLExpr original = expr; 715 716 // unwrap 717 expr = unwrapExpr(expr); 718 719 if (cast(SQLPropertyExpr)(expr) !is null) { 720 SQLPropertyExpr propertyExpr = cast(SQLPropertyExpr) expr; 721 722 SQLExpr owner = propertyExpr.getOwner(); 723 string column = propertyExpr.getName(); 724 725 if (cast(SQLName)(owner) !is null) { 726 SQLName table = cast(SQLName) owner; 727 728 SQLObject resolvedOwnerObject = propertyExpr.getResolvedOwnerObject(); 729 if (cast(SQLSubqueryTableSource)(resolvedOwnerObject) !is null 730 || cast(SQLCreateProcedureStatement)(resolvedOwnerObject) !is null 731 || cast(SQLCreateFunctionStatement)(resolvedOwnerObject) !is null) { 732 table = null; 733 } 734 735 if (cast(SQLExprTableSource)(resolvedOwnerObject) !is null) { 736 SQLExpr tableSourceExpr = (cast(SQLExprTableSource) resolvedOwnerObject).getExpr(); 737 if (cast(SQLName)(tableSourceExpr) !is null) { 738 table = cast(SQLName) tableSourceExpr; 739 } 740 } 741 742 if (table !is null) { 743 long tableHashCode64 = table.hashCode64(); 744 745 long basic = tableHashCode64; 746 basic ^= '.'; 747 basic *= FnvHash.PRIME; 748 long columnHashCode64 = FnvHash.hashCode64(basic, column); 749 750 return new TableStat.Column((cast(Object)(table)).toString(), column, columnHashCode64); 751 } 752 } 753 754 return null; 755 } 756 757 if (cast(SQLIdentifierExpr)(expr) !is null) { 758 SQLIdentifierExpr identifierExpr = cast(SQLIdentifierExpr) expr; 759 if (identifierExpr.getResolvedParameter() !is null) { 760 return null; 761 } 762 763 if (cast(SQLSubqueryTableSource)identifierExpr.getResolvedTableSource() !is null) { 764 return null; 765 } 766 767 if (identifierExpr.getResolvedDeclareItem() !is null || identifierExpr.getResolvedParameter() !is null) { 768 return null; 769 } 770 771 string column = identifierExpr.getName(); 772 773 SQLName table = null; 774 SQLTableSource tableSource = identifierExpr.getResolvedTableSource(); 775 if (cast(SQLExprTableSource)(tableSource) !is null) { 776 SQLExpr tableSourceExpr = (cast(SQLExprTableSource) tableSource).getExpr(); 777 778 if (tableSourceExpr !is null && !(cast(SQLName)(tableSourceExpr) !is null)) { 779 tableSourceExpr = unwrapExpr(tableSourceExpr); 780 } 781 782 if (cast(SQLName)(tableSourceExpr) !is null) { 783 table = cast(SQLName) tableSourceExpr; 784 } 785 } 786 787 if (table !is null) { 788 long tableHashCode64 = table.hashCode64(); 789 long basic = tableHashCode64; 790 basic ^= '.'; 791 basic *= FnvHash.PRIME; 792 long columnHashCode64 = FnvHash.hashCode64(basic, column); 793 794 return new TableStat.Column((cast(Object)(table)).toString(), column, columnHashCode64); 795 } 796 797 return new TableStat.Column("UNKNOWN", column); 798 } 799 800 if (cast(SQLMethodInvokeExpr)(expr) !is null) { 801 SQLMethodInvokeExpr methodInvokeExpr = cast(SQLMethodInvokeExpr) expr; 802 List!(SQLExpr) arguments = methodInvokeExpr.getParameters(); 803 long nameHash = methodInvokeExpr.methodNameHashCode64(); 804 if (nameHash == FnvHash.Constants.DATE_FORMAT) { 805 if (arguments.size() == 2 806 && cast(SQLName)arguments.get(0) !is null 807 && cast(SQLCharExpr)arguments.get(1) !is null) { 808 return getColumn(arguments.get(0)); 809 } 810 } 811 } 812 813 return null; 814 } 815 816 private SQLExpr unwrapExpr(SQLExpr expr) { 817 SQLExpr original = expr; 818 819 for (;;) { 820 if (cast(SQLMethodInvokeExpr)(expr) !is null) { 821 SQLMethodInvokeExpr methodInvokeExp = cast(SQLMethodInvokeExpr) expr; 822 if (methodInvokeExp.getParameters().size() == 1) { 823 SQLExpr firstExpr = methodInvokeExp.getParameters().get(0); 824 expr = firstExpr; 825 continue; 826 } 827 } 828 829 if (cast(SQLCastExpr)(expr) !is null) { 830 expr = (cast(SQLCastExpr) expr).getExpr(); 831 continue; 832 } 833 834 if (cast(SQLPropertyExpr)(expr) !is null) { 835 SQLPropertyExpr propertyExpr = cast(SQLPropertyExpr) expr; 836 837 SQLTableSource resolvedTableSource = propertyExpr.getResolvedTableSource(); 838 if (cast(SQLSubqueryTableSource)(resolvedTableSource) !is null) { 839 SQLSelect select = (cast(SQLSubqueryTableSource) resolvedTableSource).getSelect(); 840 SQLSelectQueryBlock queryBlock = select.getFirstQueryBlock(); 841 if (queryBlock !is null) { 842 if (queryBlock.getGroupBy() !is null) { 843 if (cast(SQLBinaryOpExpr)original.getParent() !is null) { 844 SQLExpr other = (cast(SQLBinaryOpExpr) original.getParent()).other(original); 845 if (!SQLExprUtils.isLiteralExpr(other)) { 846 break; 847 } 848 } 849 } 850 851 SQLSelectItem selectItem = queryBlock.findSelectItem(propertyExpr 852 .nameHashCode64()); 853 if (selectItem !is null) { 854 expr = selectItem.getExpr(); 855 continue; 856 857 } else if (queryBlock.selectItemHasAllColumn()) { 858 SQLTableSource allColumnTableSource = null; 859 860 SQLTableSource from = queryBlock.getFrom(); 861 if (cast(SQLJoinTableSource)(from) !is null) { 862 SQLSelectItem allColumnSelectItem = queryBlock.findAllColumnSelectItem(); 863 if (allColumnSelectItem !is null && cast(SQLPropertyExpr) allColumnSelectItem.getExpr() !is null) { 864 SQLExpr owner = (cast(SQLPropertyExpr) allColumnSelectItem.getExpr()).getOwner(); 865 if (cast(SQLName)(owner) !is null) { 866 allColumnTableSource = from.findTableSource((cast(SQLName) owner).nameHashCode64()); 867 } 868 } 869 } else { 870 allColumnTableSource = from; 871 } 872 873 if (allColumnTableSource is null) { 874 break; 875 } 876 877 propertyExpr = propertyExpr.clone(); 878 propertyExpr.setResolvedTableSource(allColumnTableSource); 879 880 if (cast(SQLExprTableSource)(allColumnTableSource) !is null) { 881 propertyExpr.setOwner((cast(SQLExprTableSource) allColumnTableSource).getExpr().clone()); 882 } 883 expr = propertyExpr; 884 continue; 885 } 886 } 887 } else if (cast(SQLExprTableSource)(resolvedTableSource) !is null) { 888 SQLExprTableSource exprTableSource = cast(SQLExprTableSource) resolvedTableSource; 889 if (exprTableSource.getSchemaObject() !is null) { 890 break; 891 } 892 893 SQLTableSource redirectTableSource = null; 894 SQLExpr tableSourceExpr = exprTableSource.getExpr(); 895 if (cast(SQLIdentifierExpr)(tableSourceExpr) !is null) { 896 redirectTableSource = (cast(SQLIdentifierExpr) tableSourceExpr).getResolvedTableSource(); 897 } else if (cast(SQLPropertyExpr)(tableSourceExpr) !is null) { 898 redirectTableSource = (cast(SQLPropertyExpr) tableSourceExpr).getResolvedTableSource(); 899 } 900 901 if (redirectTableSource == resolvedTableSource) { 902 redirectTableSource = null; 903 } 904 905 if (redirectTableSource !is null) { 906 propertyExpr = propertyExpr.clone(); 907 if (cast(SQLExprTableSource)(redirectTableSource) !is null) { 908 propertyExpr.setOwner((cast(SQLExprTableSource) redirectTableSource).getExpr().clone()); 909 } 910 propertyExpr.setResolvedTableSource(redirectTableSource); 911 expr = propertyExpr; 912 continue; 913 } 914 915 propertyExpr = propertyExpr.clone(); 916 propertyExpr.setOwner(tableSourceExpr); 917 expr = propertyExpr; 918 break; 919 } 920 } 921 break; 922 } 923 924 return expr; 925 } 926 927 override 928 public bool visit(SQLTruncateStatement x) { 929 setMode(x, TableStat.Mode.Delete); 930 931 foreach(SQLExprTableSource tableSource ; x.getTableSources()) { 932 SQLName name = cast(SQLName) tableSource.getExpr(); 933 TableStat stat = getTableStat(name); 934 stat.incrementDeleteCount(); 935 } 936 937 return false; 938 } 939 940 override 941 public bool visit(SQLDropViewStatement x) { 942 setMode(x, TableStat.Mode.Drop); 943 return true; 944 } 945 946 override 947 public bool visit(SQLDropTableStatement x) { 948 setMode(x, TableStat.Mode.Insert); 949 950 foreach(SQLExprTableSource tableSource ; x.getTableSources()) { 951 SQLName name = cast(SQLName) tableSource.getExpr(); 952 TableStat stat = getTableStat(name); 953 stat.incrementDropCount(); 954 } 955 956 return false; 957 } 958 959 override 960 public bool visit(SQLInsertStatement x) { 961 if (repository !is null 962 && x.getParent() is null) { 963 repository.resolve(x); 964 } 965 966 setMode(x, TableStat.Mode.Insert); 967 968 if ( cast(SQLName)x.getTableName() !is null) { 969 string ident = (cast(Object)((cast(SQLName) x.getTableName()))).toString(); 970 971 TableStat stat = getTableStat(x.getTableName()); 972 stat.incrementInsertCount(); 973 } 974 975 accept!SQLExpr(x.getColumns()); 976 accept(x.getQuery()); 977 978 return false; 979 } 980 981 protected static void putAliasMap(Map!(string, string) aliasMap, string name, string value) { 982 if (aliasMap is null || name is null) { 983 return; 984 } 985 aliasMap.put(toLower(name), value); 986 } 987 988 protected void accept(SQLObject x) { 989 if (x !is null) { 990 x.accept(this); 991 } 992 } 993 994 protected void accept(T = SQLObject)(List!(T) nodes) { 995 import std.stdio; 996 if(nodes is null ) throw new Exception("object is null"); 997 for (int i = 0, size = nodes.size(); i < size; ++i) { 998 accept(nodes.get(i)); 999 } 1000 } 1001 1002 override public bool visit(SQLSelectQueryBlock x) { 1003 if (x.getFrom() is null) { 1004 foreach(SQLSelectItem selectItem ; x.getSelectList()) { 1005 statExpr( 1006 selectItem.getExpr()); 1007 } 1008 return false; 1009 } 1010 1011 setMode(x, TableStat.Mode.Select); 1012 1013 // if (x.getFrom(cast(SQLSubqueryTableSource)()) !is null) { 1014 // x.getFrom().accept(this); 1015 // return false; 1016 // } 1017 1018 SQLTableSource from = x.getFrom(); 1019 if (from !is null) { 1020 from.accept(this); // 提前执行,获得aliasMap 1021 } 1022 1023 SQLExprTableSource into = x.getInto(); 1024 if (into !is null && cast(SQLName)into.getExpr() !is null) { 1025 SQLName intoExpr = cast(SQLName) into.getExpr(); 1026 1027 bool isParam = cast(SQLIdentifierExpr)intoExpr !is null && isParam(cast(SQLIdentifierExpr) intoExpr); 1028 1029 if (!isParam) { 1030 TableStat stat = getTableStat(intoExpr); 1031 if (stat !is null) { 1032 stat.incrementInsertCount(); 1033 } 1034 } 1035 into.accept(this); 1036 } 1037 1038 foreach(SQLSelectItem selectItem ; x.getSelectList()) { 1039 statExpr( 1040 selectItem.getExpr()); 1041 } 1042 1043 SQLExpr where = x.getWhere(); 1044 if (where !is null) { 1045 statExpr(where); 1046 } 1047 1048 SQLExpr startWith = x.getStartWith(); 1049 if (startWith !is null) { 1050 statExpr(startWith); 1051 } 1052 1053 SQLExpr connectBy = x.getConnectBy(); 1054 if (connectBy !is null) { 1055 statExpr(connectBy); 1056 } 1057 1058 SQLSelectGroupByClause groupBy = x.getGroupBy(); 1059 if (groupBy !is null) { 1060 foreach(SQLExpr expr ; groupBy.getItems()) { 1061 statExpr(expr); 1062 } 1063 } 1064 1065 SQLOrderBy orderBy = x.getOrderBy(); 1066 if (orderBy !is null) { 1067 this.visit(orderBy); 1068 } 1069 1070 SQLExpr first = x.getFirst(); 1071 if(first !is null) { 1072 statExpr(first); 1073 } 1074 1075 List!(SQLExpr) distributeBy = x.getDistributeBy(); 1076 if (distributeBy !is null) { 1077 foreach(SQLExpr expr ; distributeBy) { 1078 statExpr(expr); 1079 } 1080 } 1081 1082 List!(SQLSelectOrderByItem) sortBy = x.getSortBy(); 1083 if (sortBy !is null) { 1084 foreach(SQLSelectOrderByItem orderByItem ; sortBy) { 1085 visit(orderBy); 1086 } 1087 } 1088 1089 foreach(SQLExpr expr ; x.getForUpdateOf()) { 1090 statExpr(expr); 1091 } 1092 1093 return false; 1094 } 1095 1096 private static bool isParam(SQLIdentifierExpr x) { 1097 if (x.getResolvedParameter() !is null 1098 || x.getResolvedDeclareItem() !is null) { 1099 return true; 1100 } 1101 return false; 1102 } 1103 1104 override public void endVisit(SQLSelectQueryBlock x) { 1105 setModeOrigin(x); 1106 } 1107 1108 override public bool visit(SQLJoinTableSource x) { 1109 SQLTableSource left = x.getLeft(), right = x.getRight(); 1110 1111 left.accept(this); 1112 right.accept(this); 1113 1114 SQLExpr condition = x.getCondition(); 1115 if (condition !is null) { 1116 condition.accept(this); 1117 } 1118 1119 if (x.getUsing().size() > 0 1120 && cast(SQLExprTableSource)(left) !is null && cast(SQLExprTableSource)(right) !is null) { 1121 SQLExpr leftExpr = (cast(SQLExprTableSource) left).getExpr(); 1122 SQLExpr rightExpr = (cast(SQLExprTableSource) right).getExpr(); 1123 1124 foreach(SQLExpr expr ; x.getUsing()) { 1125 if (cast(SQLIdentifierExpr)(expr) !is null) { 1126 string name = (cast(SQLIdentifierExpr) expr).getName(); 1127 SQLPropertyExpr leftPropExpr = new SQLPropertyExpr(leftExpr, name); 1128 SQLPropertyExpr rightPropExpr = new SQLPropertyExpr(rightExpr, name); 1129 1130 leftPropExpr.setResolvedTableSource(left); 1131 rightPropExpr.setResolvedTableSource(right); 1132 1133 SQLBinaryOpExpr usingCondition = new SQLBinaryOpExpr(leftPropExpr, SQLBinaryOperator.Equality, rightPropExpr); 1134 usingCondition.accept(this); 1135 } 1136 } 1137 } 1138 1139 return false; 1140 } 1141 1142 override public bool visit(SQLPropertyExpr x) { 1143 TableStat.Column column = null; 1144 string ident = x.getName(); 1145 1146 SQLTableSource tableSource = x.getResolvedTableSource(); 1147 if (cast(SQLExprTableSource)(tableSource) !is null) { 1148 SQLExpr expr = (cast(SQLExprTableSource) tableSource).getExpr(); 1149 1150 if (cast(SQLIdentifierExpr)(expr) !is null) { 1151 SQLIdentifierExpr table = cast(SQLIdentifierExpr) expr; 1152 SQLTableSource resolvedTableSource = table.getResolvedTableSource(); 1153 if (cast(SQLExprTableSource)(resolvedTableSource) !is null) { 1154 expr = (cast(SQLExprTableSource) resolvedTableSource).getExpr(); 1155 } 1156 } else if (cast(SQLPropertyExpr)(expr) !is null) { 1157 SQLPropertyExpr table = cast(SQLPropertyExpr) expr; 1158 SQLTableSource resolvedTableSource = table.getResolvedTableSource(); 1159 if (cast(SQLExprTableSource)(resolvedTableSource) !is null) { 1160 expr = (cast(SQLExprTableSource) resolvedTableSource).getExpr(); 1161 } 1162 } 1163 1164 if (cast(SQLIdentifierExpr)(expr) !is null) { 1165 SQLIdentifierExpr table = cast(SQLIdentifierExpr) expr; 1166 1167 SQLTableSource resolvedTableSource = table.getResolvedTableSource(); 1168 if (cast(SQLWithSubqueryClause.Entry)(resolvedTableSource) !is null) { 1169 return false; 1170 } 1171 1172 column = addColumn(table.getName(), ident); 1173 1174 if (column !is null && isParentGroupBy(x)) { 1175 this.groupByColumns.add(column); 1176 } 1177 } else if (cast(SQLPropertyExpr)(expr) !is null) { 1178 SQLPropertyExpr table = cast(SQLPropertyExpr) expr; 1179 string tableName = (cast(Object)(table)).toString(); 1180 column = addColumn(tableName, ident); 1181 1182 if (column !is null && isParentGroupBy(x)) { 1183 this.groupByColumns.add(column); 1184 } 1185 } else if (cast(SQLMethodInvokeExpr)(expr) !is null) { 1186 SQLMethodInvokeExpr methodInvokeExpr = cast(SQLMethodInvokeExpr) expr; 1187 if ("table".equalsIgnoreCase(methodInvokeExpr.getMethodName()) 1188 && methodInvokeExpr.getParameters().size() == 1 1189 && cast(SQLName)methodInvokeExpr.getParameters().get(0) !is null) { 1190 SQLName table = cast(SQLName) methodInvokeExpr.getParameters().get(0); 1191 1192 string tableName = null; 1193 if (cast(SQLPropertyExpr)(table) !is null) { 1194 SQLPropertyExpr propertyExpr = cast(SQLPropertyExpr) table; 1195 SQLIdentifierExpr owner = cast(SQLIdentifierExpr) propertyExpr.getOwner(); 1196 if (propertyExpr.getResolvedTableSource() !is null 1197 && cast(SQLExprTableSource)propertyExpr.getResolvedTableSource() !is null) { 1198 SQLExpr resolveExpr = (cast(SQLExprTableSource) propertyExpr.getResolvedTableSource()).getExpr(); 1199 if (cast(SQLName)(resolveExpr) !is null) { 1200 tableName = (cast(Object)(resolveExpr)).toString() ~ "." ~ propertyExpr.getName(); 1201 } 1202 } 1203 } 1204 1205 if (tableName is null) { 1206 tableName = (cast(Object)(table)).toString(); 1207 } 1208 1209 column = addColumn(tableName, ident); 1210 } 1211 } 1212 } else if (cast(SQLWithSubqueryClause.Entry)(tableSource) !is null 1213 || cast(SQLSubqueryTableSource)(tableSource) !is null 1214 || cast(SQLUnionQueryTableSource)(tableSource) !is null 1215 || cast(SQLLateralViewTableSource)(tableSource) !is null 1216 || cast(SQLValuesTableSource)(tableSource) !is null) { 1217 return false; 1218 } else { 1219 if (x.getResolvedProcudure() !is null) { 1220 return false; 1221 } 1222 1223 if (cast(SQLParameter)x.getResolvedOwnerObject() !is null) { 1224 return false; 1225 } 1226 1227 bool skip = false; 1228 for (SQLObject parent = x.getParent();parent !is null;parent = parent.getParent()) { 1229 if (cast(SQLSelectQueryBlock)(parent) !is null) { 1230 SQLTableSource from = (cast(SQLSelectQueryBlock) parent).getFrom(); 1231 1232 // if (cast(OdpsValuesTableSource)(from) !is null) { 1233 // skip = true; 1234 // break; 1235 // } 1236 } else if (cast(SQLSelectQuery)(parent) !is null) { 1237 break; 1238 } 1239 } 1240 if (!skip) { 1241 column = handleUnkownColumn(ident); 1242 } 1243 } 1244 1245 if (column !is null) { 1246 SQLObject parent = x.getParent(); 1247 if (cast(SQLSelectOrderByItem)(parent) !is null) { 1248 parent = parent.getParent(); 1249 } 1250 if (cast(SQLPrimaryKey)(parent) !is null) { 1251 column.setPrimaryKey(true); 1252 } else if (cast(SQLUnique)(parent) !is null) { 1253 column.setUnique(true); 1254 } 1255 1256 setColumn(x, column); 1257 } 1258 1259 return false; 1260 } 1261 1262 protected bool isPseudoColumn(long hash) { 1263 return false; 1264 } 1265 1266 override public bool visit(SQLIdentifierExpr x) { 1267 if (isParam(x)) { 1268 return false; 1269 } 1270 1271 SQLTableSource tableSource = x.getResolvedTableSource(); 1272 if (cast(SQLSelectOrderByItem)x.getParent() !is null) { 1273 SQLSelectOrderByItem selectOrderByItem = cast(SQLSelectOrderByItem) x.getParent(); 1274 if (selectOrderByItem.getResolvedSelectItem() !is null) { 1275 return false; 1276 } 1277 } 1278 1279 if (tableSource is null 1280 && (x.getResolvedParameter() !is null 1281 || x.getResolvedDeclareItem() !is null)) 1282 { 1283 return false; 1284 } 1285 1286 long hash = x.nameHashCode64(); 1287 if (isPseudoColumn(hash)) { 1288 return false; 1289 } 1290 1291 if ((hash == FnvHash.Constants.LEVEL 1292 || hash == FnvHash.Constants.CONNECT_BY_ISCYCLE 1293 || hash == FnvHash.Constants.ROWNUM) 1294 && x.getResolvedColumn() is null 1295 && tableSource is null) { 1296 return false; 1297 } 1298 1299 TableStat.Column column = null; 1300 string ident = x.getName(); 1301 1302 if (cast(SQLExprTableSource)(tableSource) !is null) { 1303 SQLExpr expr = (cast(SQLExprTableSource) tableSource).getExpr(); 1304 if (cast(SQLIdentifierExpr)(expr) !is null) { 1305 SQLIdentifierExpr table = cast(SQLIdentifierExpr) expr; 1306 column = addColumn(table, ident); 1307 1308 if (column !is null && isParentGroupBy(x)) { 1309 this.groupByColumns.add(column); 1310 } 1311 } else if (cast(SQLPropertyExpr)(expr) !is null /* || cast(OracleDbLinkExpr)(expr) !is null */) { 1312 string tableName = (cast(Object)(expr)).toString(); 1313 column = addColumn(tableName, ident); 1314 1315 if (column !is null && isParentGroupBy(x)) { 1316 this.groupByColumns.add(column); 1317 } 1318 } else if (cast(SQLMethodInvokeExpr)(expr) !is null) { 1319 SQLMethodInvokeExpr methodInvokeExpr = cast(SQLMethodInvokeExpr) expr; 1320 if ("table".equalsIgnoreCase(methodInvokeExpr.getMethodName()) 1321 && methodInvokeExpr.getParameters().size() == 1 1322 && cast(SQLName)(methodInvokeExpr.getParameters().get(0)) !is null) { 1323 SQLName table = cast(SQLName) methodInvokeExpr.getParameters().get(0); 1324 1325 string tableName = null; 1326 if (cast(SQLPropertyExpr)(table) !is null) { 1327 SQLPropertyExpr propertyExpr = cast(SQLPropertyExpr) table; 1328 SQLIdentifierExpr owner = cast(SQLIdentifierExpr) propertyExpr.getOwner(); 1329 if (propertyExpr.getResolvedTableSource() !is null 1330 && cast(SQLExprTableSource) propertyExpr.getResolvedTableSource() !is null) { 1331 SQLExpr resolveExpr = (cast(SQLExprTableSource) propertyExpr.getResolvedTableSource()).getExpr(); 1332 if (cast(SQLName)(resolveExpr) !is null) { 1333 tableName = (cast(Object)(resolveExpr)).toString() ~ "." ~ propertyExpr.getName(); 1334 } 1335 } 1336 } 1337 1338 if (tableName is null) { 1339 tableName = (cast(Object)(table)).toString(); 1340 } 1341 1342 column = addColumn(tableName, ident); 1343 } 1344 } 1345 } else if (cast(SQLWithSubqueryClause.Entry)(tableSource) !is null 1346 || cast(SQLSubqueryTableSource)(tableSource) !is null 1347 || cast(SQLValuesTableSource)(tableSource) !is null 1348 || cast(SQLLateralViewTableSource)(tableSource) !is null) { 1349 return false; 1350 } else { 1351 bool skip = false; 1352 for (SQLObject parent = x.getParent();parent !is null;parent = parent.getParent()) { 1353 if (cast(SQLSelectQueryBlock)(parent) !is null) { 1354 SQLTableSource from = (cast(SQLSelectQueryBlock) parent).getFrom(); 1355 1356 // if (cast(OdpsValuesTableSource)(from) !is null) { 1357 // skip = true; 1358 // break; 1359 // } 1360 } else if (cast(SQLSelectQuery)(parent) !is null) { 1361 break; 1362 } 1363 } 1364 if (!skip) { 1365 column = handleUnkownColumn(ident); 1366 } 1367 } 1368 1369 if (column !is null) { 1370 SQLObject parent = x.getParent(); 1371 if (cast(SQLSelectOrderByItem)(parent) !is null) { 1372 parent = parent.getParent(); 1373 } 1374 if (cast(SQLPrimaryKey)(parent) !is null) { 1375 column.setPrimaryKey(true); 1376 } else if (cast(SQLUnique)(parent) !is null) { 1377 column.setUnique(true); 1378 } 1379 1380 setColumn(x, column); 1381 } 1382 1383 return false; 1384 } 1385 1386 private bool isParentSelectItem(SQLObject parent) { 1387 for (; parent !is null; parent = parent.getParent()) { 1388 if (cast(SQLSelectItem)(parent) !is null) { 1389 return true; 1390 } 1391 1392 if (cast(SQLSelectQueryBlock)(parent) !is null) { 1393 return false; 1394 } 1395 } 1396 return false; 1397 } 1398 1399 private bool isParentGroupBy(SQLObject parent) { 1400 for (; parent !is null; parent = parent.getParent()) { 1401 if (cast(SQLSelectItem)(parent) !is null) { 1402 return false; 1403 } 1404 1405 if (cast(SQLSelectGroupByClause)(parent) !is null) { 1406 return true; 1407 } 1408 } 1409 return false; 1410 } 1411 1412 private void setColumn(SQLExpr x, TableStat.Column column) { 1413 SQLObject current = x; 1414 for (;;) { 1415 SQLObject parent = current.getParent(); 1416 1417 if (parent is null) { 1418 break; 1419 } 1420 1421 if (cast(SQLSelectQueryBlock)(parent) !is null) { 1422 SQLSelectQueryBlock query = cast(SQLSelectQueryBlock) parent; 1423 if (query.getWhere() == current) { 1424 column.setWhere(true); 1425 } 1426 break; 1427 } 1428 1429 if (cast(SQLSelectGroupByClause)(parent) !is null) { 1430 SQLSelectGroupByClause groupBy = cast(SQLSelectGroupByClause) parent; 1431 if (current == groupBy.getHaving()) { 1432 column.setHaving(true); 1433 } else if (groupBy.getItems().contains(cast(SQLExpr)current)) { 1434 column.setGroupBy(true); 1435 } 1436 break; 1437 } 1438 1439 if (isParentSelectItem(parent)) { 1440 column.setSelec(true); 1441 break; 1442 } 1443 1444 if (cast(SQLJoinTableSource)(parent) !is null) { 1445 SQLJoinTableSource join = cast(SQLJoinTableSource) parent; 1446 if (join.getCondition() == current) { 1447 column.setJoin(true); 1448 } 1449 break; 1450 } 1451 1452 current = parent; 1453 } 1454 } 1455 1456 protected TableStat.Column handleUnkownColumn(string columnName) { 1457 return addColumn("UNKNOWN", columnName); 1458 } 1459 1460 override public bool visit(SQLAllColumnExpr x) { 1461 SQLTableSource tableSource = x.getResolvedTableSource(); 1462 if (tableSource is null) { 1463 return false; 1464 } 1465 1466 statAllColumn(x, tableSource); 1467 1468 return false; 1469 } 1470 1471 private void statAllColumn(SQLAllColumnExpr x, SQLTableSource tableSource) { 1472 if (cast(SQLExprTableSource)(tableSource) !is null) { 1473 statAllColumn(x, cast(SQLExprTableSource) tableSource); 1474 return; 1475 } 1476 1477 if (cast(SQLJoinTableSource)(tableSource) !is null) { 1478 SQLJoinTableSource join = cast(SQLJoinTableSource) tableSource; 1479 statAllColumn(x, join.getLeft()); 1480 statAllColumn(x, join.getRight()); 1481 } 1482 } 1483 1484 private void statAllColumn(SQLAllColumnExpr x, SQLExprTableSource tableSource) { 1485 SQLExprTableSource exprTableSource = tableSource; 1486 SQLName expr = exprTableSource.getName(); 1487 1488 SQLCreateTableStatement createStmt = null; 1489 1490 SchemaObject tableObject = exprTableSource.getSchemaObject(); 1491 if (tableObject !is null) { 1492 SQLStatement stmt = tableObject.getStatement(); 1493 if (cast(SQLCreateTableStatement)(stmt) !is null) { 1494 createStmt = cast(SQLCreateTableStatement) stmt; 1495 } 1496 } 1497 1498 if (createStmt !is null 1499 && createStmt.getTableElementList().size() > 0) { 1500 SQLName tableName = createStmt.getName(); 1501 foreach(SQLTableElement e ; createStmt.getTableElementList()) { 1502 if (cast(SQLColumnDefinition)(e) !is null) { 1503 SQLColumnDefinition columnDefinition = cast(SQLColumnDefinition) e; 1504 SQLName columnName = columnDefinition.getName(); 1505 TableStat.Column column = addColumn((cast(Object)(tableName)).toString(), (cast(Object)(columnName)).toString()); 1506 if (isParentSelectItem(x.getParent())) { 1507 column.setSelec(true); 1508 } 1509 } 1510 } 1511 } else if (expr !is null) { 1512 TableStat.Column column = addColumn((cast(Object)(expr)).toString(), "*"); 1513 if (isParentSelectItem(x.getParent())) { 1514 column.setSelec(true); 1515 } 1516 } 1517 } 1518 1519 public Map!(TableStat.Name, TableStat) getTables() { 1520 return tableStats; 1521 } 1522 1523 public bool containsTable(string tableName) { 1524 return tableStats.containsKey(new TableStat.Name(tableName)); 1525 } 1526 1527 public bool containsColumn(string tableName, string columnName) { 1528 long hashCode; 1529 1530 int p = cast(int)(tableName.indexOf('.')); 1531 if (p != -1) { 1532 SQLExpr owner = SQLUtils.toSQLExpr(tableName, dbType); 1533 hashCode = new SQLPropertyExpr(owner, columnName).hashCode64(); 1534 } else { 1535 hashCode = FnvHash.hashCode64(tableName, columnName); 1536 } 1537 return columns.containsKey(new Long(hashCode)); 1538 } 1539 1540 public TableStat.Column[] getColumns() { 1541 return columns.values(); 1542 } 1543 1544 public TableStat.Column getColumn(string tableName, string columnName) { 1545 TableStat.Column column = new TableStat.Column(tableName, columnName); 1546 1547 return this.columns.get(new Long(column.hashCode64())); 1548 } 1549 1550 override public bool visit(SQLSelectStatement x) { 1551 if (repository !is null 1552 && x.getParent() is null) { 1553 repository.resolve(x); 1554 } 1555 1556 visit(x.getSelect()); 1557 1558 return false; 1559 } 1560 1561 override public void endVisit(SQLSelectStatement x) { 1562 } 1563 1564 override 1565 public bool visit(SQLWithSubqueryClause.Entry x) { 1566 string alias_p = x.getAlias(); 1567 SQLWithSubqueryClause with_p = cast(SQLWithSubqueryClause) x.getParent(); 1568 1569 if (Boolean.TRUE.booleanValue == with_p.getRecursive()) { 1570 SQLSelect select = x.getSubQuery(); 1571 if (select !is null) { 1572 select.accept(this); 1573 } else { 1574 x.getReturningStatement().accept(this); 1575 } 1576 } else { 1577 SQLSelect select = x.getSubQuery(); 1578 if (select !is null) { 1579 select.accept(this); 1580 } else { 1581 x.getReturningStatement().accept(this); 1582 } 1583 } 1584 1585 return false; 1586 } 1587 1588 override public bool visit(SQLSubqueryTableSource x) { 1589 x.getSelect().accept(this); 1590 return false; 1591 } 1592 1593 protected bool isSimpleExprTableSource(SQLExprTableSource x) { 1594 return cast(SQLName)x.getExpr() !is null; 1595 } 1596 1597 public TableStat getTableStat(SQLExprTableSource tableSource) { 1598 return getTableStatWithUnwrap( 1599 tableSource.getExpr()); 1600 } 1601 1602 private TableStat getTableStatWithUnwrap(SQLExpr expr) { 1603 SQLExpr identExpr = null; 1604 1605 expr = unwrapExpr(expr); 1606 1607 if (cast(SQLIdentifierExpr)(expr) !is null) { 1608 SQLIdentifierExpr identifierExpr = cast(SQLIdentifierExpr) expr; 1609 1610 if (identifierExpr.nameHashCode64() == FnvHash.Constants.DUAL) { 1611 return null; 1612 } 1613 1614 if (isSubQueryOrParamOrVariant(identifierExpr)) { 1615 return null; 1616 } 1617 } 1618 1619 SQLTableSource tableSource = null; 1620 if (cast(SQLIdentifierExpr)(expr) !is null) { 1621 tableSource = (cast(SQLIdentifierExpr) expr).getResolvedTableSource(); 1622 } else if (cast(SQLPropertyExpr)(expr) !is null) { 1623 tableSource = (cast(SQLPropertyExpr) expr).getResolvedTableSource(); 1624 } 1625 1626 if (cast(SQLExprTableSource)(tableSource) !is null) { 1627 SQLExpr tableSourceExpr = (cast(SQLExprTableSource) tableSource).getExpr(); 1628 if (cast(SQLName)(tableSourceExpr) !is null) { 1629 identExpr = tableSourceExpr; 1630 } 1631 } 1632 1633 if (identExpr is null) { 1634 identExpr = expr; 1635 } 1636 1637 if (cast(SQLName)(identExpr) !is null) { 1638 return getTableStat(cast(SQLName) identExpr); 1639 } 1640 return getTableStat((cast(Object)(identExpr)).toString()); 1641 } 1642 1643 override public bool visit(SQLExprTableSource x) { 1644 if (isSimpleExprTableSource(x)) { 1645 SQLExpr expr = x.getExpr(); 1646 TableStat stat = getTableStatWithUnwrap(expr); 1647 if (stat is null) { 1648 return false; 1649 } 1650 1651 TableStat.Mode mode = getMode(); 1652 if (mode !is null) { 1653 if(mode.mark == TableStat.Mode.Delete.mark) { 1654 stat.incrementDeleteCount(); 1655 } else if(mode.mark == TableStat.Mode.Insert.mark) { 1656 stat.incrementInsertCount(); 1657 } else if(mode.mark == TableStat.Mode.Update.mark) { 1658 stat.incrementUpdateCount(); 1659 } else if(mode.mark == TableStat.Mode.Select.mark) { 1660 stat.incrementSelectCount(); 1661 } else if(mode.mark == TableStat.Mode.Merge.mark) { 1662 stat.incrementMergeCount(); 1663 } else if(mode.mark == TableStat.Mode.Drop.mark) { 1664 stat.incrementDropCount(); 1665 } 1666 } 1667 } else { 1668 accept(x.getExpr()); 1669 } 1670 1671 return false; 1672 } 1673 1674 protected bool isSubQueryOrParamOrVariant(SQLIdentifierExpr identifierExpr) { 1675 SQLObject resolvedColumnObject = identifierExpr.getResolvedColumnObject(); 1676 if (cast(SQLWithSubqueryClause.Entry)(resolvedColumnObject) !is null 1677 || cast(SQLParameter)(resolvedColumnObject) !is null 1678 || cast(SQLDeclareItem)(resolvedColumnObject) !is null) { 1679 return true; 1680 } 1681 1682 SQLObject resolvedOwnerObject = identifierExpr.getResolvedOwnerObject(); 1683 if (cast(SQLSubqueryTableSource)(resolvedOwnerObject) !is null 1684 || cast(SQLWithSubqueryClause.Entry)(resolvedOwnerObject) !is null) { 1685 return true; 1686 } 1687 1688 return false; 1689 } 1690 1691 protected bool isSubQueryOrParamOrVariant(SQLPropertyExpr x) { 1692 SQLObject resolvedOwnerObject = x.getResolvedOwnerObject(); 1693 if (cast(SQLSubqueryTableSource)(resolvedOwnerObject) !is null 1694 || cast(SQLWithSubqueryClause.Entry)(resolvedOwnerObject) !is null) { 1695 return true; 1696 } 1697 1698 SQLExpr owner = x.getOwner(); 1699 if (cast(SQLIdentifierExpr)(owner) !is null) { 1700 if (isSubQueryOrParamOrVariant(cast(SQLIdentifierExpr) owner)) { 1701 return true; 1702 } 1703 } 1704 1705 SQLTableSource tableSource = x.getResolvedTableSource(); 1706 if (cast(SQLExprTableSource)(tableSource) !is null) { 1707 SQLExprTableSource exprTableSource = cast(SQLExprTableSource) tableSource; 1708 if (exprTableSource.getSchemaObject() !is null) { 1709 return false; 1710 } 1711 1712 SQLExpr expr = exprTableSource.getExpr(); 1713 1714 if (cast(SQLIdentifierExpr)(expr) !is null) { 1715 return isSubQueryOrParamOrVariant(cast(SQLIdentifierExpr) expr); 1716 } 1717 1718 if (cast(SQLPropertyExpr)(expr) !is null) { 1719 return isSubQueryOrParamOrVariant(cast(SQLPropertyExpr) expr); 1720 } 1721 } 1722 1723 return false; 1724 } 1725 1726 override public bool visit(SQLSelectItem x) { 1727 statExpr( 1728 x.getExpr()); 1729 1730 return false; 1731 } 1732 1733 override public void endVisit(SQLSelect x) { 1734 } 1735 1736 override public bool visit(SQLSelect x) { 1737 SQLWithSubqueryClause with_p = x.getWithSubQuery(); 1738 if (with_p !is null) { 1739 with_p.accept(this); 1740 } 1741 1742 SQLSelectQuery query = x.getQuery(); 1743 if (query !is null) { 1744 query.accept(this); 1745 } 1746 1747 SQLOrderBy orderBy = x.getOrderBy(); 1748 if (orderBy !is null) { 1749 accept(x.getOrderBy()); 1750 } 1751 1752 1753 return false; 1754 } 1755 1756 override public bool visit(SQLAggregateExpr x) { 1757 this.aggregateFunctions.add(x); 1758 1759 accept!SQLExpr(x.getArguments()); 1760 accept(x.getWithinGroup()); 1761 accept(x.getOver()); 1762 return false; 1763 } 1764 1765 override public bool visit(SQLMethodInvokeExpr x) { 1766 this.functions.add(x); 1767 1768 accept!SQLExpr(x.getParameters()); 1769 return false; 1770 } 1771 1772 override public bool visit(SQLUpdateStatement x) { 1773 if (repository !is null 1774 && x.getParent() is null) { 1775 repository.resolve(x); 1776 } 1777 1778 setMode(x, TableStat.Mode.Update); 1779 1780 SQLTableSource tableSource = x.getTableSource(); 1781 if (cast(SQLExprTableSource)(tableSource) !is null) { 1782 SQLName identName = (cast(SQLExprTableSource) tableSource).getName(); 1783 TableStat stat = getTableStat(identName); 1784 stat.incrementUpdateCount(); 1785 } else { 1786 tableSource.accept(this); 1787 } 1788 1789 accept(x.getFrom()); 1790 1791 accept!SQLUpdateSetItem((x.getItems())); 1792 accept(x.getWhere()); 1793 1794 return false; 1795 } 1796 1797 override public bool visit(SQLDeleteStatement x) { 1798 if (repository !is null 1799 && x.getParent() is null) { 1800 repository.resolve(x); 1801 } 1802 1803 setMode(x, TableStat.Mode.Delete); 1804 1805 if (cast(SQLSubqueryTableSource) x.getTableSource() !is null) { 1806 SQLSelectQuery selectQuery = (cast(SQLSubqueryTableSource) x.getTableSource()).getSelect().getQuery(); 1807 if (cast(SQLSelectQueryBlock)(selectQuery) !is null) { 1808 SQLSelectQueryBlock subQueryBlock = (cast(SQLSelectQueryBlock) selectQuery); 1809 subQueryBlock.getWhere().accept(this); 1810 } 1811 } 1812 1813 TableStat stat = getTableStat(x.getTableName()); 1814 stat.incrementDeleteCount(); 1815 1816 accept(x.getWhere()); 1817 1818 return false; 1819 } 1820 1821 override public bool visit(SQLInListExpr x) { 1822 if (x.isNot()) { 1823 handleCondition(x.getExpr(), "NOT IN", x.getTargetList()); 1824 } else { 1825 handleCondition(x.getExpr(), "IN", x.getTargetList()); 1826 } 1827 1828 return true; 1829 } 1830 1831 override 1832 public bool visit(SQLInSubQueryExpr x) { 1833 if (x.isNot()) { 1834 handleCondition(x.getExpr(), "NOT IN"); 1835 } else { 1836 handleCondition(x.getExpr(), "IN"); 1837 } 1838 return true; 1839 } 1840 1841 override public bool visit(SQLCreateTableStatement x) { 1842 if (repository !is null 1843 && x.getParent() is null) { 1844 repository.resolve(x); 1845 } 1846 1847 foreach(SQLTableElement e ; x.getTableElementList()) { 1848 e.setParent(x); 1849 } 1850 1851 TableStat stat = getTableStat(x.getName()); 1852 stat.incrementCreateCount(); 1853 1854 accept!SQLTableElement(x.getTableElementList()); 1855 1856 if (x.getInherits() !is null) { 1857 x.getInherits().accept(this); 1858 } 1859 1860 if (x.getSelect() !is null) { 1861 x.getSelect().accept(this); 1862 } 1863 1864 return false; 1865 } 1866 1867 override public bool visit(SQLColumnDefinition x) { 1868 string tableName = null; 1869 { 1870 SQLObject parent = x.getParent(); 1871 if (cast(SQLCreateTableStatement)(parent) !is null) { 1872 tableName = (cast(Object)(cast(SQLCreateTableStatement) parent).getName()).toString(); 1873 } 1874 } 1875 1876 if (tableName is null) { 1877 return true; 1878 } 1879 1880 string columnName = (cast(Object)x.getName()).toString(); 1881 TableStat.Column column = addColumn(tableName, columnName); 1882 if (x.getDataType() !is null) { 1883 column.setDataType(x.getDataType().getName()); 1884 } 1885 1886 foreach(SQLColumnConstraint item ; x.getConstraints()) { 1887 if (cast(SQLPrimaryKey)(item) !is null) { 1888 column.setPrimaryKey(true); 1889 } else if (cast(SQLUnique)(item) !is null) { 1890 column.setUnique(true); 1891 } 1892 } 1893 1894 return false; 1895 } 1896 1897 override 1898 public bool visit(SQLCallStatement x) { 1899 return false; 1900 } 1901 1902 override 1903 public void endVisit(SQLCommentStatement x) { 1904 1905 } 1906 1907 override 1908 public bool visit(SQLCommentStatement x) { 1909 return false; 1910 } 1911 1912 override public bool visit(SQLCurrentOfCursorExpr x) { 1913 return false; 1914 } 1915 1916 override 1917 public bool visit(SQLAlterTableAddColumn x) { 1918 SQLAlterTableStatement stmt = cast(SQLAlterTableStatement) x.getParent(); 1919 string table = (cast(Object)stmt.getName()).toString(); 1920 1921 foreach(SQLColumnDefinition column ; x.getColumns()) { 1922 string columnName = (cast(Object)column.getName()).toString(); 1923 addColumn(table, columnName); 1924 } 1925 return false; 1926 } 1927 1928 override 1929 public void endVisit(SQLAlterTableAddColumn x) { 1930 1931 } 1932 1933 override 1934 public bool visit(SQLRollbackStatement x) { 1935 return false; 1936 } 1937 1938 override public bool visit(SQLCreateViewStatement x) { 1939 if (repository !is null 1940 && x.getParent() is null) { 1941 repository.resolve(x); 1942 } 1943 1944 x.getSubQuery().accept(this); 1945 return false; 1946 } 1947 1948 override public bool visit(SQLAlterViewStatement x) { 1949 if (repository !is null 1950 && x.getParent() is null) { 1951 repository.resolve(x); 1952 } 1953 1954 x.getSubQuery().accept(this); 1955 return false; 1956 } 1957 1958 override 1959 public bool visit(SQLAlterTableDropForeignKey x) { 1960 return false; 1961 } 1962 1963 override 1964 public bool visit(SQLUseStatement x) { 1965 return false; 1966 } 1967 1968 override 1969 public bool visit(SQLAlterTableDisableConstraint x) { 1970 return false; 1971 } 1972 1973 override 1974 public bool visit(SQLAlterTableEnableConstraint x) { 1975 return false; 1976 } 1977 1978 override 1979 public bool visit(SQLAlterTableStatement x) { 1980 if (repository !is null 1981 && x.getParent() is null) { 1982 repository.resolve(x); 1983 } 1984 1985 TableStat stat = getTableStat(x.getName()); 1986 stat.incrementAlterCount(); 1987 1988 1989 foreach(SQLAlterTableItem item ; x.getItems()) { 1990 item.setParent(x); 1991 item.accept(this); 1992 } 1993 1994 return false; 1995 } 1996 1997 override 1998 public bool visit(SQLAlterTableDropConstraint x) { 1999 return false; 2000 } 2001 2002 override 2003 public bool visit(SQLDropIndexStatement x) { 2004 setMode(x, TableStat.Mode.DropIndex); 2005 SQLExprTableSource table = x.getTableName(); 2006 if (table !is null) { 2007 SQLName name = cast(SQLName) table.getExpr(); 2008 TableStat stat = getTableStat(name); 2009 stat.incrementDropIndexCount(); 2010 } 2011 return false; 2012 } 2013 2014 override 2015 public bool visit(SQLCreateIndexStatement x) { 2016 setMode(x, TableStat.Mode.CreateIndex); 2017 2018 SQLName name = cast(SQLName) (cast(SQLExprTableSource) x.getTable()).getExpr(); 2019 2020 string table = (cast(Object)(name)).toString(); 2021 2022 TableStat stat = getTableStat(name); 2023 stat.incrementCreateIndexCount(); 2024 2025 foreach(SQLSelectOrderByItem item ; x.getItems()) { 2026 SQLExpr expr = item.getExpr(); 2027 if (cast(SQLIdentifierExpr)(expr) !is null) { 2028 SQLIdentifierExpr identExpr = cast(SQLIdentifierExpr) expr; 2029 string columnName = identExpr.getName(); 2030 addColumn(table, columnName); 2031 } 2032 } 2033 2034 return false; 2035 } 2036 2037 override 2038 public bool visit(SQLForeignKeyImpl x) { 2039 2040 foreach(SQLName column ; x.getReferencingColumns()) { 2041 column.accept(this); 2042 } 2043 2044 string table = x.getReferencedTableName().getSimpleName(); 2045 2046 TableStat stat = getTableStat(x.getReferencedTableName()); 2047 stat.incrementReferencedCount(); 2048 foreach(SQLName column ; x.getReferencedColumns()) { 2049 string columnName = column.getSimpleName(); 2050 addColumn(table, columnName); 2051 } 2052 2053 return false; 2054 } 2055 2056 override 2057 public bool visit(SQLDropSequenceStatement x) { 2058 return false; 2059 } 2060 2061 override 2062 public bool visit(SQLDropTriggerStatement x) { 2063 return false; 2064 } 2065 2066 override 2067 public bool visit(SQLDropUserStatement x) { 2068 return false; 2069 } 2070 2071 override 2072 public bool visit(SQLGrantStatement x) { 2073 if (x.getOn() !is null && (x.getObjectType().name.length == 0 || x.getObjectType() == SQLObjectType.TABLE)) { 2074 x.getOn().accept(this); 2075 } 2076 return false; 2077 } 2078 2079 override 2080 public bool visit(SQLRevokeStatement x) { 2081 if (x.getOn() !is null) { 2082 x.getOn().accept(this); 2083 } 2084 return false; 2085 } 2086 2087 override 2088 public bool visit(SQLDropDatabaseStatement x) { 2089 return false; 2090 } 2091 2092 override 2093 public bool visit(SQLAlterTableAddIndex x) { 2094 foreach(SQLSelectOrderByItem item ; x.getItems()) { 2095 item.accept(this); 2096 } 2097 2098 SQLName table = (cast(SQLAlterTableStatement) x.getParent()).getName(); 2099 TableStat tableStat = this.getTableStat(table); 2100 tableStat.incrementCreateIndexCount(); 2101 return false; 2102 } 2103 2104 override public bool visit(SQLCheck x) { 2105 x.getExpr().accept(this); 2106 return false; 2107 } 2108 2109 override public bool visit(SQLCreateTriggerStatement x) { 2110 SQLExprTableSource on = x.getOn(); 2111 on.accept(this); 2112 return false; 2113 } 2114 2115 override public bool visit(SQLDropFunctionStatement x) { 2116 return false; 2117 } 2118 2119 override public bool visit(SQLDropTableSpaceStatement x) { 2120 return false; 2121 } 2122 2123 override public bool visit(SQLDropProcedureStatement x) { 2124 return false; 2125 } 2126 2127 override 2128 public bool visit(SQLAlterTableRename x) { 2129 return false; 2130 } 2131 2132 override 2133 public bool visit(SQLArrayExpr x) { 2134 accept!SQLExpr(x.getValues()); 2135 2136 SQLExpr exp = x.getExpr(); 2137 if (cast(SQLIdentifierExpr)(exp) !is null) { 2138 if ((cast(SQLIdentifierExpr) exp).getName() == ("ARRAY")) { 2139 return false; 2140 } 2141 } 2142 exp.accept(this); 2143 return false; 2144 } 2145 2146 override 2147 public bool visit(SQLOpenStatement x) { 2148 return false; 2149 } 2150 2151 override 2152 public bool visit(SQLFetchStatement x) { 2153 return false; 2154 } 2155 2156 override 2157 public bool visit(SQLCloseStatement x) { 2158 return false; 2159 } 2160 2161 override 2162 public bool visit(SQLCreateProcedureStatement x) { 2163 if (repository !is null 2164 && x.getParent() is null) { 2165 repository.resolve(x); 2166 } 2167 2168 accept(x.getBlock()); 2169 return false; 2170 } 2171 2172 override 2173 public bool visit(SQLCreateFunctionStatement x) { 2174 if (repository !is null 2175 && x.getParent() is null) { 2176 repository.resolve(x); 2177 } 2178 2179 accept(x.getBlock()); 2180 return false; 2181 } 2182 2183 override 2184 public bool visit(SQLBlockStatement x) { 2185 if (repository !is null 2186 && x.getParent() is null) { 2187 repository.resolve(x); 2188 } 2189 2190 foreach(SQLParameter param ; x.getParameters()) { 2191 param.setParent(x); 2192 param.accept(this); 2193 } 2194 2195 foreach(SQLStatement stmt ; x.getStatementList()) { 2196 stmt.accept(this); 2197 } 2198 2199 SQLStatement exception = x.getException(); 2200 if (exception !is null) { 2201 exception.accept(this); 2202 } 2203 2204 return false; 2205 } 2206 2207 override 2208 public bool visit(SQLShowTablesStatement x) { 2209 return false; 2210 } 2211 2212 override 2213 public bool visit(SQLDeclareItem x) { 2214 return false; 2215 } 2216 2217 override 2218 public bool visit(SQLPartitionByHash x) { 2219 return false; 2220 } 2221 2222 override 2223 public bool visit(SQLPartitionByRange x) { 2224 return false; 2225 } 2226 2227 override 2228 public bool visit(SQLPartitionByList x) { 2229 return false; 2230 } 2231 2232 override 2233 public bool visit(SQLPartition x) { 2234 return false; 2235 } 2236 2237 override 2238 public bool visit(SQLSubPartition x) { 2239 return false; 2240 } 2241 2242 override 2243 public bool visit(SQLSubPartitionByHash x) { 2244 return false; 2245 } 2246 2247 override 2248 public bool visit(SQLPartitionValue x) { 2249 return false; 2250 } 2251 2252 override 2253 public bool visit(SQLAlterDatabaseStatement x) { 2254 return true; 2255 } 2256 2257 override 2258 public bool visit(SQLAlterTableConvertCharSet x) { 2259 return false; 2260 } 2261 2262 override 2263 public bool visit(SQLAlterTableDropPartition x) { 2264 return false; 2265 } 2266 2267 override 2268 public bool visit(SQLAlterTableReOrganizePartition x) { 2269 return false; 2270 } 2271 2272 override 2273 public bool visit(SQLAlterTableCoalescePartition x) { 2274 return false; 2275 } 2276 2277 override 2278 public bool visit(SQLAlterTableTruncatePartition x) { 2279 return false; 2280 } 2281 2282 override 2283 public bool visit(SQLAlterTableDiscardPartition x) { 2284 return false; 2285 } 2286 2287 override 2288 public bool visit(SQLAlterTableImportPartition x) { 2289 return false; 2290 } 2291 2292 override 2293 public bool visit(SQLAlterTableAnalyzePartition x) { 2294 return false; 2295 } 2296 2297 override 2298 public bool visit(SQLAlterTableCheckPartition x) { 2299 return false; 2300 } 2301 2302 override 2303 public bool visit(SQLAlterTableOptimizePartition x) { 2304 return false; 2305 } 2306 2307 override 2308 public bool visit(SQLAlterTableRebuildPartition x) { 2309 return false; 2310 } 2311 2312 override 2313 public bool visit(SQLAlterTableRepairPartition x) { 2314 return false; 2315 } 2316 2317 override public bool visit(SQLSequenceExpr x) { 2318 return false; 2319 } 2320 2321 override 2322 public bool visit(SQLMergeStatement x) { 2323 if (repository !is null 2324 && x.getParent() is null) { 2325 repository.resolve(x); 2326 } 2327 2328 setMode(x.getUsing(), TableStat.Mode.Select); 2329 x.getUsing().accept(this); 2330 2331 setMode(x, TableStat.Mode.Merge); 2332 2333 SQLTableSource into = x.getInto(); 2334 if (cast(SQLExprTableSource)(into) !is null) { 2335 string ident = (cast(Object)(cast(SQLExprTableSource) into).getExpr()).toString(); 2336 TableStat stat = getTableStat(ident); 2337 stat.incrementMergeCount(); 2338 } else { 2339 into.accept(this); 2340 } 2341 2342 x.getOn().accept(this); 2343 2344 if (x.getUpdateClause() !is null) { 2345 x.getUpdateClause().accept(this); 2346 } 2347 2348 if (x.getInsertClause() !is null) { 2349 x.getInsertClause().accept(this); 2350 } 2351 2352 return false; 2353 } 2354 2355 override 2356 public bool visit(SQLSetStatement x) { 2357 return false; 2358 } 2359 2360 public List!(SQLMethodInvokeExpr) getFunctions() { 2361 return this.functions; 2362 } 2363 2364 override public bool visit(SQLCreateSequenceStatement x) { 2365 return false; 2366 } 2367 2368 override 2369 public bool visit(SQLAlterTableAddConstraint x) { 2370 SQLConstraint constraint = x.getConstraint(); 2371 if (cast(SQLUniqueConstraint)(constraint) !is null) { 2372 SQLAlterTableStatement stmt = cast(SQLAlterTableStatement) x.getParent(); 2373 TableStat tableStat = this.getTableStat(stmt.getName()); 2374 tableStat.incrementCreateIndexCount(); 2375 } 2376 return true; 2377 } 2378 2379 override 2380 public bool visit(SQLAlterTableDropIndex x) { 2381 SQLAlterTableStatement stmt = cast(SQLAlterTableStatement) x.getParent(); 2382 TableStat tableStat = this.getTableStat(stmt.getName()); 2383 tableStat.incrementDropIndexCount(); 2384 return false; 2385 } 2386 2387 override 2388 public bool visit(SQLAlterTableDropPrimaryKey x) { 2389 SQLAlterTableStatement stmt = cast(SQLAlterTableStatement) x.getParent(); 2390 TableStat tableStat = this.getTableStat(stmt.getName()); 2391 tableStat.incrementDropIndexCount(); 2392 return false; 2393 } 2394 2395 override 2396 public bool visit(SQLAlterTableDropKey x) { 2397 SQLAlterTableStatement stmt = cast(SQLAlterTableStatement) x.getParent(); 2398 TableStat tableStat = this.getTableStat(stmt.getName()); 2399 tableStat.incrementDropIndexCount(); 2400 return false; 2401 } 2402 2403 override 2404 public bool visit(SQLDescribeStatement x) { 2405 string tableName = (cast(Object)x.getObject()).toString(); 2406 2407 TableStat tableStat = this.getTableStat(x.getObject()); 2408 tableStat.incrementDropIndexCount(); 2409 2410 SQLName column = x.getColumn(); 2411 if (column !is null) { 2412 string columnName = (cast(Object)(column)).toString(); 2413 this.addColumn(tableName, columnName); 2414 } 2415 return false; 2416 } 2417 2418 override public bool visit(SQLExplainStatement x) { 2419 if (repository !is null 2420 && x.getParent() is null) { 2421 repository.resolve(x); 2422 } 2423 2424 if (x.getStatement() !is null) { 2425 accept(x.getStatement()); 2426 } 2427 2428 return false; 2429 } 2430 2431 override public bool visit(SQLCreateMaterializedViewStatement x) { 2432 if (repository !is null 2433 && x.getParent() is null) { 2434 repository.resolve(x); 2435 } 2436 return true; 2437 } 2438 2439 override public bool visit(SQLReplaceStatement x) { 2440 if (repository !is null 2441 && x.getParent() is null) { 2442 repository.resolve(x); 2443 } 2444 2445 setMode(x, TableStat.Mode.Replace); 2446 2447 SQLName tableName = x.getTableName(); 2448 2449 TableStat stat = getTableStat(tableName); 2450 2451 if (stat !is null) { 2452 stat.incrementInsertCount(); 2453 } 2454 2455 accept!SQLExpr(x.getColumns()); 2456 accept!(ValuesClause)(x.getValuesList()); 2457 accept(x.getQuery()); 2458 2459 return false; 2460 } 2461 2462 protected void statExpr(SQLExpr x) { 2463 auto clazz = typeid(x); 2464 if (clazz == typeid(SQLIdentifierExpr)) { 2465 visit(cast(SQLIdentifierExpr) x); 2466 } else if (clazz == typeid(SQLPropertyExpr)) { 2467 visit(cast(SQLPropertyExpr) x); 2468 // } else if (clazz == typeid(SQLAggregateExpr)) { 2469 // visit(cast(SQLAggregateExpr) x); 2470 } else if (clazz == typeid(SQLBinaryOpExpr)) { 2471 visit(cast(SQLBinaryOpExpr) x); 2472 // } else if (clazz == typeid(SQLCharExpr)) { 2473 // visit(cast(SQLCharExpr) x); 2474 // } else if (clazz == typeid(SQLNullExpr)) { 2475 // visit(cast(SQLNullExpr) x); 2476 // } else if (clazz == typeid(SQLIntegerExpr)) { 2477 // visit(cast(SQLIntegerExpr) x); 2478 // } else if (clazz == typeid(SQLNumberExpr)) { 2479 // visit(cast(SQLNumberExpr) x); 2480 // } else if (clazz == typeid(SQLMethodInvokeExpr)) { 2481 // visit(cast(SQLMethodInvokeExpr) x); 2482 // } else if (clazz == typeid(SQLVariantRefExpr)) { 2483 // visit(cast(SQLVariantRefExpr) x); 2484 // } else if (clazz == typeid(SQLBinaryOpExprGroup)) { 2485 // visit(cast(SQLBinaryOpExprGroup) x); 2486 } else if (cast(SQLLiteralExpr)(x) !is null) { 2487 // skip 2488 } else { 2489 x.accept(this); 2490 } 2491 } 2492 2493 override public bool visit(SQLAlterFunctionStatement x) { 2494 return false; 2495 } 2496 override public bool visit(SQLDropSynonymStatement x) { 2497 return false; 2498 } 2499 2500 override public bool visit(SQLAlterTypeStatement x) { 2501 return false; 2502 } 2503 override public bool visit(SQLAlterProcedureStatement x) { 2504 return false; 2505 } 2506 2507 override public bool visit(SQLExprStatement x) { 2508 SQLExpr expr = x.getExpr(); 2509 2510 if (cast(SQLName)(expr) !is null) { 2511 return false; 2512 } 2513 2514 return true; 2515 } 2516 2517 override 2518 public bool visit(SQLDropTypeStatement x) { 2519 return false; 2520 } 2521 2522 override 2523 public bool visit(SQLExternalRecordFormat x) { 2524 return false; 2525 } 2526 2527 override public bool visit(SQLCreateDatabaseStatement x) { 2528 return false; 2529 } 2530 2531 override 2532 public bool visit(SQLAlterTableExchangePartition x) { 2533 SQLExprTableSource table = x.getTable(); 2534 if (table !is null) { 2535 table.accept(this); 2536 } 2537 return false; 2538 } 2539 2540 override public bool visit(SQLDumpStatement x) { 2541 if (repository !is null 2542 && x.getParent() is null) { 2543 repository.resolve(x); 2544 } 2545 2546 SQLExprTableSource into = x.getInto(); 2547 if (into !is null) { 2548 into.accept(this); 2549 } 2550 2551 SQLSelect select = x.getSelect(); 2552 if (select !is null) { 2553 select.accept(this); 2554 } 2555 2556 return false; 2557 } 2558 }