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 }