From 29fbe65a77b27b8cc00ee3790dcc88514b639945 Mon Sep 17 00:00:00 2001 From: wenshao Date: Fri, 1 Sep 2017 21:58:09 +0800 Subject: [PATCH] improved sql parser. --- .../java/com/alibaba/druid/sql/SQLUtils.java | 2 +- .../alibaba/druid/sql/ast/SQLObjectImpl.java | 6 +- .../druid/sql/ast/expr/SQLIdentifierExpr.java | 2 +- .../druid/sql/ast/expr/SQLPropertyExpr.java | 14 + .../mysql/visitor/MySqlSchemaStatVisitor.java | 6 +- .../odps/visitor/OdpsSchemaStatVisitor.java | 3 +- .../oracle/ast/expr/OracleDbLinkExpr.java | 27 +- .../oracle/parser/OracleExprParser.java | 32 ++- .../oracle/parser/OracleStatementParser.java | 2 - .../visitor/OracleSchemaStatVisitor.java | 34 +-- .../visitor/PGSchemaStatVisitor.java | 8 +- .../visitor/SQLServerSchemaStatVisitor.java | 4 +- .../sql/visitor/SQLASTOutputVisitor.java | 85 ++++-- .../druid/sql/visitor/SchemaStatVisitor.java | 256 +++++++++--------- .../com/alibaba/druid/stat/TableStat.java | 48 ++-- .../java/com/alibaba/druid/util/FnvHash.java | 11 + .../sql/MySqlParameterizedBenchmark.java | 21 +- .../druid/benckmark/sql/Templates.java | 2 +- ...ySqlParameterizedOutputVisitorTest_43.java | 1 + .../bvt/sql/oracle/DesensitizationTest.java | 4 +- .../DesensitizationTest_createTable.java | 2 +- .../DesensitizationTest_createView.java | 6 +- .../oracle/DesensitizationTest_delete.java | 2 +- .../oracle/DesensitizationTest_insert.java | 4 +- .../oracle/DesensitizationTest_update.java | 2 +- .../bvt/sql/oracle/OracleMergeTest4.java | 2 +- .../sql/oracle/OracleTruncateTableTest.java | 5 +- .../OracleUpdateTest5_encoding_error.java | 67 +++++ .../sql/oracle/insert/OracleInsertTest15.java | 5 +- .../OracleInsertTest21_encoding_error.java | 74 +++++ .../sql/oracle/select/OracleSelectTest24.java | 2 +- .../sql/oracle/select/OracleSelectTest28.java | 2 +- .../sql/oracle/select/OracleSelectTest80.java | 67 +++++ .../sql/oracle/demo/OracleResourceTest2.java | 2 +- 34 files changed, 538 insertions(+), 272 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleUpdateTest5_encoding_error.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/insert/OracleInsertTest21_encoding_error.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest80.java diff --git a/src/main/java/com/alibaba/druid/sql/SQLUtils.java b/src/main/java/com/alibaba/druid/sql/SQLUtils.java index 1d8b2314b0..ea809d4607 100644 --- a/src/main/java/com/alibaba/druid/sql/SQLUtils.java +++ b/src/main/java/com/alibaba/druid/sql/SQLUtils.java @@ -895,7 +895,7 @@ public class SQLUtils { } tableName = normalize(tableName); - long hash = Utils.fnv_32_lower(tableName); + long hash = FnvHash.hashCode64(tableName); return Utils.hex_t(hash); } diff --git a/src/main/java/com/alibaba/druid/sql/ast/SQLObjectImpl.java b/src/main/java/com/alibaba/druid/sql/ast/SQLObjectImpl.java index 9dff9c19ad..cfc588970e 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/SQLObjectImpl.java +++ b/src/main/java/com/alibaba/druid/sql/ast/SQLObjectImpl.java @@ -199,7 +199,11 @@ public abstract class SQLObjectImpl implements SQLObject { } public boolean hasAfterComment() { - List comments = getAfterCommentsDirect(); + if (attributes == null) { + return false; + } + + List comments = (List) attributes.get("format.after_comment"); if (comments == null) { return false; } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLIdentifierExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLIdentifierExpr.java index ae4c502003..9daf9a4d3c 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLIdentifierExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLIdentifierExpr.java @@ -112,7 +112,7 @@ public class SQLIdentifierExpr extends SQLExprImpl implements SQLName { public SQLIdentifierExpr simplify() { String normalized = SQLUtils.normalize(name); if (normalized != name) { - return new SQLIdentifierExpr(name, hashCode64); + return new SQLIdentifierExpr(normalized, hashCode64); } return this; } diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLPropertyExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLPropertyExpr.java index 4207ffe7bf..0b13a1132d 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLPropertyExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLPropertyExpr.java @@ -284,4 +284,18 @@ public class SQLPropertyExpr extends SQLExprImpl implements SQLName { public boolean nameEquals(String name) { return SQLUtils.nameEquals(this.name, name); } + + public SQLPropertyExpr simplify() { + String normalizedName = SQLUtils.normalize(name); + SQLExpr normalizedOwner = this.owner; + if (normalizedOwner instanceof SQLIdentifierExpr) { + normalizedOwner = ((SQLIdentifierExpr) normalizedOwner).simplify(); + } + + if (normalizedName != name || normalizedOwner != owner) { + return new SQLPropertyExpr(normalizedOwner, normalizedName, hashCode64); + } + + return this; + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java index 76b66a766c..84031afdd3 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlSchemaStatVisitor.java @@ -444,7 +444,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS SQLName columnName = x.getColumnName(); if (columnName != null) { - addColumn(table, columnName.getSimpleName(), tableName.nameHashCode64(), columnName.nameHashCode64()); + addColumn(table, columnName.getSimpleName()); } } @@ -954,7 +954,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS SQLName column = x.getColumnName(); String columnName = column.toString(); - addColumn(tableName, columnName, table.nameHashCode64(), column.nameHashCode64()); + addColumn(tableName, columnName); return false; } @@ -972,7 +972,7 @@ public class MySqlSchemaStatVisitor extends SchemaStatVisitor implements MySqlAS SQLName column = x.getNewColumnDefinition().getName(); String columnName = column.toString(); - addColumn(tableName, columnName, table.nameHashCode64(), column.nameHashCode64()); + addColumn(tableName, columnName); return false; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java index 4c68e05500..feba3d5c82 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsSchemaStatVisitor.java @@ -68,8 +68,7 @@ public class OdpsSchemaStatVisitor extends SchemaStatVisitor implements OdpsASTV SQLExpr tableName = tableSource.getExpr(); if (tableName instanceof SQLName) { - String ident = ((SQLName) tableName).toString(); - TableStat stat = getTableStat(tableName); + TableStat stat = getTableStat((SQLName) tableName); stat.incrementInsertCount(); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleDbLinkExpr.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleDbLinkExpr.java index 770a008c65..66c26134fb 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleDbLinkExpr.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/ast/expr/OracleDbLinkExpr.java @@ -76,11 +76,8 @@ public class OracleDbLinkExpr extends SQLExprImpl implements SQLName, OracleExpr @Override public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((dbLink == null) ? 0 : dbLink.hashCode()); - result = prime * result + ((expr == null) ? 0 : expr.hashCode()); - return result; + long value = hashCode64(); + return (int)(value ^ (value >>> 32)); } @Override @@ -95,21 +92,7 @@ public class OracleDbLinkExpr extends SQLExprImpl implements SQLName, OracleExpr return false; } OracleDbLinkExpr other = (OracleDbLinkExpr) obj; - if (dbLink == null) { - if (other.dbLink != null) { - return false; - } - } else if (!dbLink.equals(other.dbLink)) { - return false; - } - if (expr == null) { - if (other.expr != null) { - return false; - } - } else if (!expr.equals(other.expr)) { - return false; - } - return true; + return this.hashCode64() == other.hashCode64(); } public OracleDbLinkExpr clone() { @@ -138,14 +121,14 @@ public class OracleDbLinkExpr extends SQLExprImpl implements SQLName, OracleExpr if (expr instanceof SQLName) { hash = ((SQLName) expr).hashCode64(); - hash ^= '.'; + hash ^= '@'; hash *= FnvHash.PRIME; } else if (expr == null){ hash = FnvHash.BASIC; } else { hash = FnvHash.fnv1a_64_lower(expr.toString()); - hash ^= '.'; + hash ^= '@'; hash *= FnvHash.PRIME; } hash = FnvHash.hashCode64(hash, dbLink); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java index a006e46b0f..d7705cf78f 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java @@ -480,7 +480,7 @@ public class OracleExprParser extends SQLExprParser { if (acceptLPAREN) { accept(Token.LPAREN); } - + if (lexer.token() == Token.PLUS) { lexer.nextToken(); accept(Token.RPAREN); @@ -508,7 +508,7 @@ public class OracleExprParser extends SQLExprParser { return primaryRest(treatExpr); } } - + return super.methodRest(expr, false); } @@ -878,11 +878,31 @@ public class OracleExprParser extends SQLExprParser { interval.setValue(new SQLCharExpr(lexer.stringVal())); lexer.nextToken(); - - OracleIntervalType type = OracleIntervalType.valueOf(lexer.stringVal()); + OracleIntervalType type; + if (lexer.identifierEquals(FnvHash.Constants.YEAR)) { + lexer.nextToken(); + type = OracleIntervalType.YEAR; + } else if (lexer.identifierEquals(FnvHash.Constants.MONTH)) { + lexer.nextToken(); + type = OracleIntervalType.MONTH; + } else if (lexer.identifierEquals(FnvHash.Constants.DAY)) { + lexer.nextToken(); + type = OracleIntervalType.DAY; + } else if (lexer.identifierEquals(FnvHash.Constants.HOUR)) { + lexer.nextToken(); + type = OracleIntervalType.HOUR; + } else if (lexer.identifierEquals(FnvHash.Constants.MINUTE)) { + lexer.nextToken(); + type = OracleIntervalType.MINUTE; + } else if (lexer.identifierEquals(FnvHash.Constants.SECOND)) { + lexer.nextToken(); + type = OracleIntervalType.SECOND; + } else { + throw new ParserException("illegal interval type. " + lexer.info()); + } + interval.setType(type); - lexer.nextToken(); - + if (lexer.token() == Token.LPAREN) { lexer.nextToken(); if (lexer.token() != Token.LITERAL_INT) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java index 38d2b899c6..7dd9f68016 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleStatementParser.java @@ -922,8 +922,6 @@ public class OracleStatementParser extends SQLStatementParser { if (lexer.token() == Token.ELSE) { lexer.nextToken(); - - SQLIfStatement.Else elseItem = new SQLIfStatement.Else(); this.parseStatementList(elseItem.getStatements(), -1, elseItem); stmt.setElseItem(elseItem); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleSchemaStatVisitor.java index 5b3c4a657d..de362af6b1 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleSchemaStatVisitor.java @@ -151,9 +151,7 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle } if (tableExpr instanceof SQLName) { - String ident = tableExpr.toString(); - - TableStat stat = getTableStat(ident); + TableStat stat = getTableStat((SQLName) tableExpr); stat.incrementUpdateCount(); } else { tableSource.accept(this); @@ -176,13 +174,13 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle } public boolean visit(OracleSelectQueryBlock x) { - if (x.getInto() instanceof SQLName) { - String tableName = x.getInto().toString(); - TableStat stat = getTableStat(tableName); - if (stat != null) { - stat.incrementInsertCount(); - } - } + SQLExprTableSource into = x.getInto(); +// if (into != null && into.getExpr() instanceof SQLName) { +// TableStat stat = getTableStat((SQLName) into.getExpr()); +// if (stat != null) { +// stat.incrementInsertCount(); +// } +// } return visit((SQLSelectQueryBlock) x); } @@ -638,9 +636,7 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle public boolean visit(InsertIntoClause x) { if (x.getTableName() instanceof SQLName) { - String ident = ((SQLName) x.getTableName()).toString(); - - TableStat stat = getTableStat(ident); + TableStat stat = getTableStat(x.getTableName()); stat.incrementInsertCount(); } @@ -729,8 +725,7 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle @Override public boolean visit(OracleLockTableStatement x) { - String tableName = x.getTable().toString(); - getTableStat(tableName); + getTableStat(x.getTable()); return false; } @@ -902,11 +897,12 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle @Override public boolean visit(OracleAlterTableModify x) { SQLAlterTableStatement stmt = (SQLAlterTableStatement) x.getParent(); - String table = stmt.getName().toString(); + SQLName tableName = stmt.getName(); + String table = tableName.toString(); for (SQLColumnDefinition column : x.getColumns()) { - String columnName = column.getName().toString(); - addColumn(table, columnName); + SQLName columnName = column.getName(); + addColumn(table, columnName.toString()); } @@ -1333,7 +1329,7 @@ public class OracleSchemaStatVisitor extends SchemaStatVisitor implements Oracle } if (sql != null) { - List stmtList = SQLUtils.parseStatements(sql, getDbType()); + List stmtList = SQLUtils.parseStatements(sql, dbType); for (SQLStatement stmt : stmtList) { stmt.accept(this); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGSchemaStatVisitor.java index 7fa3609060..1058254669 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGSchemaStatVisitor.java @@ -139,9 +139,7 @@ public class PGSchemaStatVisitor extends SchemaStatVisitor implements PGASTVisit SQLName tableName = x.getTableName(); { - String ident = tableName.toString(); - - TableStat stat = getTableStat(ident); + TableStat stat = getTableStat(tableName); stat.incrementInsertCount(); } @@ -181,9 +179,7 @@ public class PGSchemaStatVisitor extends SchemaStatVisitor implements PGASTVisit x.getWith().accept(this); } - String ident = x.getTableName().toString(); - - TableStat stat = getTableStat(ident); + TableStat stat = getTableStat(x.getTableName()); stat.incrementUpdateCount(); accept(x.getFrom()); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerSchemaStatVisitor.java index af93a8a2aa..dbb7023478 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerSchemaStatVisitor.java @@ -84,9 +84,7 @@ public class SQLServerSchemaStatVisitor extends SchemaStatVisitor implements SQL @Override public boolean visit(SQLServerUpdateStatement x) { - String ident = x.getTableName().toString(); - - TableStat stat = getTableStat(ident); + TableStat stat = getTableStat(x.getTableName()); stat.incrementUpdateCount(); accept(x.getItems()); diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java index f2200ecbbe..2998c89453 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -41,6 +41,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreatePackageStatemen import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleForStatement; import com.alibaba.druid.util.JdbcConstants; import com.alibaba.druid.util.JdbcUtils; +import oracle.sql.SQLUtil; import static com.alibaba.druid.util.Utils.getBoolean; @@ -52,7 +53,6 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet } protected final Appendable appender; - private String indent = "\t"; protected int indentCount = 0; protected boolean ucase = true; protected int selectListNumberOfLine = 5; @@ -111,6 +111,15 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet if (tableMapping == null) { tableMapping = new HashMap(); } + + if (srcTable.indexOf('.') >= 0) { + SQLExpr expr = SQLUtils.toSQLExpr(srcTable, dbType); + if (expr instanceof SQLPropertyExpr) { + srcTable = ((SQLPropertyExpr) expr).simplify().toString(); + } + } else { + srcTable = SQLUtils.normalize(srcTable); + } tableMapping.put(srcTable, destTable); } @@ -207,7 +216,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet try { this.appender.append(value); } catch (IOException e) { - throw new RuntimeException("println error", e); + throw new RuntimeException("print error", e); } } @@ -290,6 +299,10 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet } private static int paramCount(SQLExpr x) { + if (x instanceof SQLName) { + return 1; + } + if (x instanceof SQLMethodInvokeExpr) { List params = ((SQLMethodInvokeExpr) x).getParameters(); int paramCount = 1; @@ -319,14 +332,20 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet protected void printSelectList(List selectList) { this.indentCount++; for (int i = 0, lineItemCount = 0, size = selectList.size() - ; i < size; ++i, ++lineItemCount) { + ; i < size + ; ++i, ++lineItemCount) + { SQLSelectItem selectItem = selectList.get(i); SQLExpr selectItemExpr = selectItem.getExpr(); int paramCount = paramCount(selectItemExpr); - if (selectItemExpr instanceof SQLMethodInvokeExpr + + boolean methodOrBinary = (!(selectItemExpr instanceof SQLName)) + && (selectItemExpr instanceof SQLMethodInvokeExpr || selectItemExpr instanceof SQLAggregateExpr - || selectItemExpr instanceof SQLBinaryOpExpr) { + || selectItemExpr instanceof SQLBinaryOpExpr); + + if (methodOrBinary) { lineItemCount += (paramCount - 1); } @@ -335,9 +354,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet if (preSelectItem.getAfterCommentsDirect() != null) { lineItemCount = 0; println(); - } else if (selectItemExpr instanceof SQLMethodInvokeExpr - || selectItemExpr instanceof SQLAggregateExpr - || selectItemExpr instanceof SQLBinaryOpExpr) { + } else if (methodOrBinary) { if (lineItemCount >= selectListNumberOfLine) { lineItemCount = paramCount; println(); @@ -376,9 +393,17 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet } } - public void printIndent() { - for (int i = 0; i < this.indentCount; ++i) { - print0(this.indent); + protected void printIndent() { + if (this.appender == null) { + return; + } + + try { + for (int i = 0; i < this.indentCount; ++i) { + this.appender.append('\t'); + } + } catch (IOException e) { + throw new RuntimeException("print error", e); } } @@ -388,7 +413,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet return; } - print0("\n"); + print('\n'); lines++; printIndent(); } @@ -398,11 +423,6 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet println(); } - protected void println0(String text) { - print0(text); - println(); - } - // //////////////////// public boolean visit(SQLBetweenExpr x) { @@ -1658,24 +1678,28 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet print0(ucase ? "SELECT " : "select "); - if (JdbcConstants.INFORMIX.equals(dbType)) { + final boolean informix =JdbcConstants.INFORMIX.equals(dbType); + if (informix) { printFetchFirst(x); } - if (SQLSetQuantifier.ALL == x.getDistionOption()) { + final int distinctOption = x.getDistionOption(); + if (SQLSetQuantifier.ALL == distinctOption) { print0(ucase ? "ALL " : "all "); - } else if (SQLSetQuantifier.DISTINCT == x.getDistionOption()) { + } else if (SQLSetQuantifier.DISTINCT == distinctOption) { print0(ucase ? "DISTINCT " : "distinct "); - } else if (SQLSetQuantifier.UNIQUE == x.getDistionOption()) { + } else if (SQLSetQuantifier.UNIQUE == distinctOption) { print0(ucase ? "UNIQUE " : "unique "); } - printSelectList(x.getSelectList()); + printSelectList( + x.getSelectList()); - if (x.getInto() != null) { + SQLExprTableSource into = x.getInto(); + if (into != null) { println(); print0(ucase ? "INTO " : "into "); - x.getInto().accept(this); + into.accept(this); } SQLTableSource from = x.getFrom(); @@ -1689,7 +1713,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet if (where != null) { println(); print0(ucase ? "WHERE " : "where "); - where.accept(this); + printExpr(where); } printHierarchical(x); @@ -1706,7 +1730,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet orderBy.accept(this); } - if (!JdbcConstants.INFORMIX.equals(dbType)) { + if (!informix) { printFetchFirst(x); } @@ -1785,12 +1809,17 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet SQLExpr expr = x.getExpr(); - printExpr(expr); + if (expr instanceof SQLIdentifierExpr) { + print0(((SQLIdentifierExpr) expr).getName()); + } else { + printExpr(expr); + } String alias = x.getAlias(); if (alias != null && alias.length() > 0) { print0(ucase ? " AS " : " as "); - if (alias.indexOf(' ') == -1 || alias.charAt(0) == '"' || alias.charAt(0) == '\'') { + char c0 = alias.charAt(0); + if (alias.indexOf(' ') == -1 || c0 == '"' || c0 == '\'') { print0(alias); } else { print('"'); diff --git a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java index b0ca06ce30..4632391fc3 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java @@ -102,24 +102,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { this.parameters = parameters; } - public TableStat getTableStat(String ident) { - return getTableStat(ident, null); - } - - protected Column addColumn(String tableName, String columnName) { - return addColumn(tableName, columnName, 0, 0); - } - - protected Column addColumn(String tableName, String columnName, long table_hash, long name_hash) { - Column column = this.getColumn(tableName, columnName); - if (column == null && columnName != null) { - column = new Column(tableName, columnName); - columns.put(column.hashCode64(), column); - } - return column; - } - - public TableStat getTableStat(String tableName, String alias) { + public TableStat getTableStat(String tableName) { tableName = handleName(tableName); TableStat.Name tableNameObj = new TableStat.Name(tableName); @@ -131,6 +114,49 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { return stat; } + public TableStat getTableStat(SQLName tableName) { + String strName = tableName.toString(); + long hashCode64 = tableName.hashCode64(); + + if (hashCode64 == FnvHash.Constants.DUAL) { + return null; + } + + TableStat.Name tableNameObj = new TableStat.Name(strName, hashCode64); + TableStat stat = tableStats.get(tableNameObj); + if (stat == null) { + stat = new TableStat(); + tableStats.put(new TableStat.Name(strName, hashCode64), stat); + } + return stat; + } + + protected Column addColumn(String tableName, String columnName) { + Column column = this.getColumn(tableName, columnName); + if (column == null && columnName != null) { + column = new Column(tableName, columnName); + columns.put(column.hashCode64(), column); + } + return column; + } + + protected Column addColumn(SQLName table, String columnName) { + String tableName = table.toString(); + long tableHashCode64 = table.hashCode64(); + + long basic = tableHashCode64; + basic ^= '.'; + basic *= FnvHash.PRIME; + long columnHashCode64 = FnvHash.hashCode64(basic, columnName); + + Column column = this.columns.get(columnHashCode64); + if (column == null && columnName != null) { + column = new Column(tableName, columnName, columnHashCode64); + columns.put(columnHashCode64, column); + } + return column; + } + private String handleName(String ident) { int len = ident.length(); if (ident.charAt(0) == '[' && ident.charAt(len - 1) == ']') { @@ -171,9 +197,6 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { return ident; } - public void setAliasMap() { - } - protected Mode getMode() { return mode; } @@ -455,11 +478,11 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { protected SQLASTVisitor createOrderByVisitor(SQLOrderBy x) { final SQLASTVisitor orderByVisitor; - if (JdbcConstants.MYSQL.equals(getDbType())) { + if (JdbcConstants.MYSQL.equals(dbType)) { orderByVisitor = new MySqlOrderByStatVisitor(x); - } else if (JdbcConstants.POSTGRESQL.equals(getDbType())) { + } else if (JdbcConstants.POSTGRESQL.equals(dbType)) { orderByVisitor = new PGOrderByStatVisitor(x); - } else if (JdbcConstants.ORACLE.equals(getDbType())) { + } else if (JdbcConstants.ORACLE.equals(dbType)) { orderByVisitor = new OracleOrderByStatVisitor(x); } else { orderByVisitor = new OrderByStatVisitor(x); @@ -550,11 +573,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { return; } - Relationship relationship = new Relationship(); - relationship.setLeft(leftColumn); - relationship.setRight(rightColumn); - relationship.setOperator(operator); - + Relationship relationship = new Relationship(leftColumn, rightColumn, operator); this.relationships.add(relationship); } @@ -581,9 +600,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { } if (condition == null) { - condition = new Condition(); - condition.setColumn(column); - condition.setOperator(operator); + condition = new Condition(column, operator); this.conditions.add(condition); } @@ -592,7 +609,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { if (valueColumn != null) { continue; } - Object value = SQLEvalVisitorUtils.eval(getDbType(), item, parameters, false); + Object value = SQLEvalVisitorUtils.eval(dbType, item, parameters, false); if (value == SQLEvalVisitor.EVAL_VALUE_NULL) { value = null; } @@ -617,13 +634,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { String column = propertyExpr.getName(); if (owner instanceof SQLName) { - String tableName = owner.toString(); - String table = tableName; -// String tableNameLower = tableName.toLowerCase(); -// -// if (aliasMap.containsKey(tableNameLower)) { -// table = aliasMap.get(tableNameLower); -// } + SQLName table = (SQLName) owner; SQLObject resolvedOwnerObject = propertyExpr.getResolvedOwnerObject(); if (resolvedOwnerObject instanceof SQLSubqueryTableSource @@ -635,12 +646,19 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { if (resolvedOwnerObject instanceof SQLExprTableSource) { SQLExpr tableSourceExpr = ((SQLExprTableSource) resolvedOwnerObject).getExpr(); if (tableSourceExpr instanceof SQLName) { - table = tableSourceExpr.toString(); + table = (SQLName) tableSourceExpr; } } if (table != null) { - return new Column(table, column); + long tableHashCode64 = table.hashCode64(); + + long basic = tableHashCode64; + basic ^= '.'; + basic *= FnvHash.PRIME; + long columnHashCode64 = FnvHash.hashCode64(basic, column); + + return new Column(table.toString(), column, columnHashCode64); } } @@ -663,27 +681,28 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { String column = identifierExpr.getName(); - String table = null; + SQLName table = null; SQLTableSource tableSource = identifierExpr.getResolvedTableSource(); if (tableSource instanceof SQLExprTableSource) { SQLExpr tableSourceExpr = ((SQLExprTableSource) tableSource).getExpr(); - SQLName tableName = null; if (tableSourceExpr != null && !(tableSourceExpr instanceof SQLName)) { tableSourceExpr = unwrapExpr(tableSourceExpr); } if (tableSourceExpr instanceof SQLName) { - tableName = (SQLName) tableSourceExpr; - } - - if (tableName != null) { - table = tableName.toString(); + table = (SQLName) tableSourceExpr; } } if (table != null) { - return new Column(table, column); + long tableHashCode64 = table.hashCode64(); + long basic = tableHashCode64; + basic ^= '.'; + basic *= FnvHash.PRIME; + long columnHashCode64 = FnvHash.hashCode64(basic, column); + + return new Column(table.toString(), column, columnHashCode64); } return new Column("UNKNOWN", column); @@ -809,10 +828,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { for (SQLExprTableSource tableSource : x.getTableSources()) { SQLName name = (SQLName) tableSource.getExpr(); - - String ident = name.toString(); - - TableStat stat = getTableStat(ident); + TableStat stat = getTableStat(name); stat.incrementDeleteCount(); } @@ -831,9 +847,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { for (SQLExprTableSource tableSource : x.getTableSources()) { SQLName name = (SQLName) tableSource.getExpr(); - String ident = name.toString(); - - TableStat stat = getTableStat(ident); + TableStat stat = getTableStat(name); stat.incrementDropCount(); } @@ -852,7 +866,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { if (x.getTableName() instanceof SQLName) { String ident = ((SQLName) x.getTableName()).toString(); - TableStat stat = getTableStat(ident); + TableStat stat = getTableStat(x.getTableName()); stat.incrementInsertCount(); } @@ -905,8 +919,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { boolean isParam = intoExpr instanceof SQLIdentifierExpr && isParam((SQLIdentifierExpr) intoExpr); if (!isParam) { - String ident = intoExpr.toString(); - TableStat stat = getTableStat(ident); + TableStat stat = getTableStat(intoExpr); if (stat != null) { stat.incrementInsertCount(); } @@ -972,7 +985,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { return false; } - public static boolean isParam(SQLIdentifierExpr x) { + private static boolean isParam(SQLIdentifierExpr x) { if (x.getResolvedParameter() != null || x.getResolvedDeclareItem() != null) { return true; @@ -1048,7 +1061,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { return false; } - column = addColumn(table.getName(), ident, table.nameHashCode64(), x.nameHashCode64()); + column = addColumn(table.getName(), ident); if (column != null && isParentGroupBy(x)) { this.groupByColumns.add(column); @@ -1056,7 +1069,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { } else if (expr instanceof SQLPropertyExpr) { SQLPropertyExpr table = (SQLPropertyExpr) expr; String tableName = table.toString(); - column = addColumn(tableName, ident, 0, x.nameHashCode64()); + column = addColumn(tableName, ident); if (column != null && isParentGroupBy(x)) { this.groupByColumns.add(column); @@ -1085,7 +1098,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { tableName = table.toString(); } - column = addColumn(tableName, ident, 0, x.nameHashCode64()); + column = addColumn(tableName, ident); } } } else if (tableSource instanceof SQLWithSubqueryClause.Entry @@ -1135,11 +1148,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { return false; } - protected String aliasWrap(String name) { - return name; - } - - public boolean isPseudoColumn(long hash) { + protected boolean isPseudoColumn(long hash) { return false; } @@ -1183,14 +1192,14 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { SQLExpr expr = ((SQLExprTableSource) tableSource).getExpr(); if (expr instanceof SQLIdentifierExpr) { SQLIdentifierExpr table = (SQLIdentifierExpr) expr; - column = addColumn(table.getName(), ident, table.nameHashCode64(), hash); + column = addColumn(table, ident); if (column != null && isParentGroupBy(x)) { this.groupByColumns.add(column); } } else if (expr instanceof SQLPropertyExpr || expr instanceof OracleDbLinkExpr) { String tableName = expr.toString(); - column = addColumn(tableName, ident, 0, hash); + column = addColumn(tableName, ident); if (column != null && isParentGroupBy(x)) { this.groupByColumns.add(column); @@ -1219,7 +1228,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { tableName = table.toString(); } - column = addColumn(tableName, ident, 0, x.nameHashCode64()); + column = addColumn(tableName, ident); } } } else if (tableSource instanceof SQLWithSubqueryClause.Entry @@ -1263,31 +1272,29 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { } private boolean isParentSelectItem(SQLObject parent) { - if (parent == null) { - return false; + for (; parent != null; parent = parent.getParent()) { + if (parent instanceof SQLSelectItem) { + return true; + } + + if (parent instanceof SQLSelectQueryBlock) { + return false; + } } - - if (parent instanceof SQLSelectItem) { - return true; - } - - if (parent instanceof SQLSelectQueryBlock) { - return false; - } - - return isParentSelectItem(parent.getParent()); + return false; } private boolean isParentGroupBy(SQLObject parent) { - if (parent == null) { - return false; + for (; parent != null; parent = parent.getParent()) { + if (parent instanceof SQLSelectItem) { + return false; + } + + if (parent instanceof SQLSelectGroupByClause) { + return true; + } } - - if (parent instanceof SQLSelectGroupByClause) { - return true; - } - - return isParentGroupBy(parent.getParent()); + return false; } private void setColumn(SQLExpr x, Column column) { @@ -1362,7 +1369,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { if (e instanceof SQLColumnDefinition) { SQLColumnDefinition columnDefinition = (SQLColumnDefinition) e; SQLName columnName = columnDefinition.getName(); - Column column = addColumn(tableName.toString(), columnName.toString(), tableName.hashCode64(), columnName.hashCode64()); + Column column = addColumn(tableName.toString(), columnName.toString()); if (isParentSelectItem(x.getParent())) { column.setSelec(true); } @@ -1458,12 +1465,12 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { } public TableStat getTableStat(SQLExprTableSource tableSource) { - return getTableStat( + return getTableStatWithUnwrap( tableSource.getExpr()); } - public TableStat getTableStat(SQLExpr expr) { - String ident = null; + private TableStat getTableStatWithUnwrap(SQLExpr expr) { + SQLExpr identExpr = null; expr = unwrapExpr(expr); @@ -1489,21 +1496,24 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { if (tableSource instanceof SQLExprTableSource) { SQLExpr tableSourceExpr = ((SQLExprTableSource) tableSource).getExpr(); if (tableSourceExpr instanceof SQLName) { - ident = tableSourceExpr.toString(); + identExpr = tableSourceExpr; } } - if (ident == null) { - ident = expr.toString(); + if (identExpr == null) { + identExpr = expr; } - return getTableStat(ident); + if (identExpr instanceof SQLName) { + return getTableStat((SQLName) identExpr); + } + return getTableStat(identExpr.toString()); } public boolean visit(SQLExprTableSource x) { if (isSimpleExprTableSource(x)) { SQLExpr expr = x.getExpr(); - TableStat stat = getTableStat(expr); + TableStat stat = getTableStatWithUnwrap(expr); if (stat == null) { return false; } @@ -1649,9 +1659,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { SQLTableSource tableSource = x.getTableSource(); if (tableSource instanceof SQLExprTableSource) { SQLName identName = ((SQLExprTableSource) tableSource).getName(); - String ident = identName.toString(); - - TableStat stat = getTableStat(ident); + TableStat stat = getTableStat(identName); stat.incrementUpdateCount(); } else { tableSource.accept(this); @@ -1673,8 +1681,6 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { setMode(x, Mode.Delete); - String tableName = x.getTableName().toString(); - if (x.getTableSource() instanceof SQLSubqueryTableSource) { SQLSelectQuery selectQuery = ((SQLSubqueryTableSource) x.getTableSource()).getSelect().getQuery(); if (selectQuery instanceof SQLSelectQueryBlock) { @@ -1683,7 +1689,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { } } - TableStat stat = getTableStat(tableName); + TableStat stat = getTableStat(x.getTableName()); stat.incrementDeleteCount(); accept(x.getWhere()); @@ -1728,9 +1734,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { e.setParent(x); } - String tableName = x.getName().toString(); - - TableStat stat = getTableStat(tableName); + TableStat stat = getTableStat(x.getName()); stat.incrementCreateCount(); accept(x.getTableElementList()); @@ -1854,8 +1858,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { repository.resolve(x); } - String tableName = x.getName().toString(); - TableStat stat = getTableStat(tableName); + TableStat stat = getTableStat(x.getName()); stat.incrementAlterCount(); @@ -1878,10 +1881,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { SQLExprTableSource table = x.getTableName(); if (table != null) { SQLName name = (SQLName) table.getExpr(); - - String ident = name.toString(); - - TableStat stat = getTableStat(ident); + TableStat stat = getTableStat(name); stat.incrementDropIndexCount(); } return false; @@ -1895,7 +1895,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { String table = name.toString(); - TableStat stat = getTableStat(table); + TableStat stat = getTableStat(name); stat.incrementCreateIndexCount(); for (SQLSelectOrderByItem item : x.getItems()) { @@ -1919,7 +1919,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { String table = x.getReferencedTableName().getSimpleName(); - TableStat stat = getTableStat(table); + TableStat stat = getTableStat(x.getReferencedTableName()); stat.incrementReferencedCount(); for (SQLName column : x.getReferencedColumns()) { String columnName = column.getSimpleName(); @@ -1971,7 +1971,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { item.accept(this); } - String table = ((SQLAlterTableStatement) x.getParent()).getName().toString(); + SQLName table = ((SQLAlterTableStatement) x.getParent()).getName(); TableStat tableStat = this.getTableStat(table); tableStat.incrementCreateIndexCount(); return false; @@ -2240,9 +2240,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { SQLConstraint constraint = x.getConstraint(); if (constraint instanceof SQLUniqueConstraint) { SQLAlterTableStatement stmt = (SQLAlterTableStatement) x.getParent(); - String tableName = stmt.getName().toString(); - - TableStat tableStat = this.getTableStat(tableName); + TableStat tableStat = this.getTableStat(stmt.getName()); tableStat.incrementCreateIndexCount(); } return true; @@ -2251,9 +2249,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { @Override public boolean visit(SQLAlterTableDropIndex x) { SQLAlterTableStatement stmt = (SQLAlterTableStatement) x.getParent(); - String tableName = stmt.getName().toString(); - - TableStat tableStat = this.getTableStat(tableName); + TableStat tableStat = this.getTableStat(stmt.getName()); tableStat.incrementDropIndexCount(); return false; } @@ -2261,9 +2257,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { @Override public boolean visit(SQLAlterTableDropPrimaryKey x) { SQLAlterTableStatement stmt = (SQLAlterTableStatement) x.getParent(); - String tableName = stmt.getName().toString(); - - TableStat tableStat = this.getTableStat(tableName); + TableStat tableStat = this.getTableStat(stmt.getName()); tableStat.incrementDropIndexCount(); return false; } @@ -2271,9 +2265,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { @Override public boolean visit(SQLAlterTableDropKey x) { SQLAlterTableStatement stmt = (SQLAlterTableStatement) x.getParent(); - String tableName = stmt.getName().toString(); - - TableStat tableStat = this.getTableStat(tableName); + TableStat tableStat = this.getTableStat(stmt.getName()); tableStat.incrementDropIndexCount(); return false; } @@ -2282,7 +2274,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { public boolean visit(SQLDescribeStatement x) { String tableName = x.getObject().toString(); - TableStat tableStat = this.getTableStat(tableName); + TableStat tableStat = this.getTableStat(x.getObject()); tableStat.incrementDropIndexCount(); SQLName column = x.getColumn(); diff --git a/src/main/java/com/alibaba/druid/stat/TableStat.java b/src/main/java/com/alibaba/druid/stat/TableStat.java index 82406deb74..df624a57f1 100644 --- a/src/main/java/com/alibaba/druid/stat/TableStat.java +++ b/src/main/java/com/alibaba/druid/stat/TableStat.java @@ -189,8 +189,12 @@ public class TableStat { private final long hashCode64; public Name(String name){ + this(name, FnvHash.hashCode64(name)); + } + + public Name(String name, long hashCode64){ this.name = name; - hashCode64 = FnvHash.hashCode64(name); + this.hashCode64 = hashCode64; } public String getName() { @@ -225,34 +229,24 @@ public class TableStat { private Column right; private String operator; - public Relationship(){ - + public Relationship(Column left, Column right, String operator) { + this.left = left; + this.right = right; + this.operator = operator; } public Column getLeft() { return left; } - public void setLeft(Column left) { - this.left = left; - } - public Column getRight() { return right; } - public void setRight(Column right) { - this.right = right; - } - public String getOperator() { return operator; } - public void setOperator(String operator) { - this.operator = operator; - } - @Override public int hashCode() { final int prime = 31; @@ -308,27 +302,23 @@ public class TableStat { public static class Condition { - private Column column; - private String operator; + private final Column column; + private final String operator; + private final List values = new ArrayList(); - private List values = new ArrayList(); + public Condition(Column column, String operator) { + this.column = column; + this.operator = operator; + } public Column getColumn() { return column; } - public void setColumn(Column column) { - this.column = column; - } - public String getOperator() { return operator; } - public void setOperator(String operator) { - this.operator = operator; - } - public List getValues() { return values; } @@ -440,6 +430,12 @@ public class TableStat { } } + public Column(String table, String name, long hashCode64){ + this.table = table; + this.name = name; + this.hashCode64 = hashCode64; + } + public String getTable() { return table; } diff --git a/src/main/java/com/alibaba/druid/util/FnvHash.java b/src/main/java/com/alibaba/druid/util/FnvHash.java index 415e1755e6..d3a54c6b96 100644 --- a/src/main/java/com/alibaba/druid/util/FnvHash.java +++ b/src/main/java/com/alibaba/druid/util/FnvHash.java @@ -101,6 +101,10 @@ public final class FnvHash { } public static long hashCode64(long basic, String name) { + if (name == null) { + return basic; + } + boolean quote = false; int len = name.length(); @@ -387,5 +391,12 @@ public final class FnvHash { long RECURSIVE = fnv1a_64_lower("RECURSIVE"); long ROLLUP = fnv1a_64_lower("ROLLUP"); long CUBE = fnv1a_64_lower("CUBE"); + + long YEAR = fnv1a_64_lower("YEAR"); + long MONTH = fnv1a_64_lower("MONTH"); + long DAY = fnv1a_64_lower("DAY"); + long HOUR = fnv1a_64_lower("HOUR"); + long MINUTE = fnv1a_64_lower("MINUTE"); + long SECOND = fnv1a_64_lower("SECOND"); } } diff --git a/src/test/java/com/alibaba/druid/benckmark/sql/MySqlParameterizedBenchmark.java b/src/test/java/com/alibaba/druid/benckmark/sql/MySqlParameterizedBenchmark.java index 9a379aff9b..3a51b0e097 100644 --- a/src/test/java/com/alibaba/druid/benckmark/sql/MySqlParameterizedBenchmark.java +++ b/src/test/java/com/alibaba/druid/benckmark/sql/MySqlParameterizedBenchmark.java @@ -10,6 +10,9 @@ import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; import com.alibaba.druid.sql.visitor.SQLASTVisitor; import com.alibaba.druid.sql.visitor.SchemaStatVisitor; import com.alibaba.druid.util.JdbcConstants; +import com.alibaba.druid.wall.WallUtils; +import com.alibaba.druid.wall.WallVisitor; +import com.alibaba.druid.wall.spi.MySqlWallProvider; import junit.framework.TestCase; import org.junit.Test; @@ -28,7 +31,7 @@ public class MySqlParameterizedBenchmark extends TestCase { + "WHERE `sub_biz_order_id` = ? AND `biz_order_type` = ? AND `id` = ? AND `ti_id` = ? AND `optype` = ? AND `root_id` = ?"; for (int i = 0; i < 5; ++i) { -// perf(sql); // 6740 6201 4752 4514 + perf(sql); // 6740 6201 4752 4514 4391 4218 4127 4124 // perf(sql2); // 2948 2928 2869 2780 2502 // perf(sql3); // 15093 10392 10416 10154 10007 9126 8907 // perf(sql4); // 4429 4190 4023 3747 @@ -38,9 +41,11 @@ public class MySqlParameterizedBenchmark extends TestCase { // perf_parse(sql3); // 9174 5875 5805 5536 5717 // perf_parse(sql4); // 2953 2502 - perf_stat(sql); // 11793 13628 13561 13259 9946 7637 7444 7389 7326 +// perf_stat(sql); // 15214 11793 13628 13561 13259 9946 7637 7444 7389 7326 7176 6687 5973 5660 -// perf_resolve(sql); // 4970 4586 3600 +// perf_resolve(sql); // 4970 4586 3600 3595 + +// perf_wall(sql); // 9695 5017 } } public void perf(String sql) { @@ -86,4 +91,14 @@ public class MySqlParameterizedBenchmark extends TestCase { long millis = System.currentTimeMillis() - startMillis; System.out.println("millis : " + millis); } + + MySqlWallProvider provider = new MySqlWallProvider(); + public void perf_wall(String sql) { + long startMillis = System.currentTimeMillis(); + for (int i = 0; i < 1000 * 1000; ++i) { + provider.checkValid(sql); + } + long millis = System.currentTimeMillis() - startMillis; + System.out.println("millis : " + millis); + } } diff --git a/src/test/java/com/alibaba/druid/benckmark/sql/Templates.java b/src/test/java/com/alibaba/druid/benckmark/sql/Templates.java index 0dfba9b8e0..bb81f52ab8 100644 --- a/src/test/java/com/alibaba/druid/benckmark/sql/Templates.java +++ b/src/test/java/com/alibaba/druid/benckmark/sql/Templates.java @@ -18,7 +18,7 @@ public class Templates { public static String parameterize(SQLStatement ast, Set physicalNames, List params) { List parameters = null; - StringBuilder out = new StringBuilder(); + Appendable out = new StringBuilder(); SQLASTOutputVisitor visitor = new MySqlOutputVisitor(out); visitor.setParameterized(true); visitor.setParameterizedMergeInList(true); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_43.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_43.java index f54a91cc99..06e2e30a9e 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_43.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_43.java @@ -55,6 +55,7 @@ public class MySqlParameterizedOutputVisitorTest_43 extends TestCase { stmt.accept(schemaStatVisitor); JSONArray srcArray = new JSONArray(); for (Map.Entry entry : schemaStatVisitor.getTables().entrySet()) { + System.out.println(entry.getKey().getName()); srcArray.add(entry.getKey().getName()); } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/DesensitizationTest.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/DesensitizationTest.java index 0545c0a72f..4d438f918d 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/DesensitizationTest.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/DesensitizationTest.java @@ -21,7 +21,7 @@ public class DesensitizationTest extends TestCase { System.out.println(desens_Sql); assertEquals("SELECT id, name\n" + - "FROM T_771DB81F525E1E75\n" + + "FROM T_6635BB1415F4C1B5\n" + "WHERE id = ?", desens_Sql); } @@ -38,7 +38,7 @@ public class DesensitizationTest extends TestCase { System.out.println(desens_Sql); assertEquals("SELECT id, name\n" + - "FROM T_771DB81F525E1E75\n" + + "FROM T_6635BB1415F4C1B5\n" + "WHERE id = ?", desens_Sql); } } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/DesensitizationTest_createTable.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/DesensitizationTest_createTable.java index 77ba5bb94d..4f3927f498 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/DesensitizationTest_createTable.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/DesensitizationTest_createTable.java @@ -24,7 +24,7 @@ public class DesensitizationTest_createTable extends TestCase { System.out.println("-------------------"); System.out.println(desens_Sql); - assertEquals("CREATE TABLE T_69BFC132C09344DE (\n" + + assertEquals("CREATE TABLE T_0C9879D1E6FFA3BE (\n" + "\tcustomer_id number(10) NOT NULL,\n" + "\tcustomer_name varchar2(50) NOT NULL,\n" + "\tcity varchar2(50)\n" + diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/DesensitizationTest_createView.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/DesensitizationTest_createView.java index 6b17e18663..50737d537b 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/DesensitizationTest_createView.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/DesensitizationTest_createView.java @@ -28,11 +28,11 @@ public class DesensitizationTest_createView extends TestCase { System.out.println("-------------------"); System.out.println(desens_Sql); - assertEquals("CREATE VIEW T_0E06E66B87C28B46\n" + + assertEquals("CREATE VIEW T_2BB49C83CE16E971\n" + "AS\n" + "SELECT suppliers.supplier_id, orders.quantity, orders.price\n" + - "FROM T_126BF2439561E30E\n" + - "\tINNER JOIN T_C5B90BBF325E96EC ON suppliers.supplier_id = orders.supplier_id \n" + + "FROM T_2EBB0E6843F14AEE\n" + + "\tINNER JOIN T_00125D9250BE8B4C ON suppliers.supplier_id = orders.supplier_id \n" + "WHERE suppliers.supplier_name = ?;", desens_Sql); Map tableMapping = new HashMap(); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/DesensitizationTest_delete.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/DesensitizationTest_delete.java index 797dde6f8b..745d574b05 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/DesensitizationTest_delete.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/DesensitizationTest_delete.java @@ -21,7 +21,7 @@ public class DesensitizationTest_delete extends TestCase { System.out.println("-------------------"); System.out.println(desens_Sql); - assertEquals("DELETE FROM T_69BFC132C09344DE\n" + + assertEquals("DELETE FROM T_0C9879D1E6FFA3BE\n" + "WHERE last_name = ?;", desens_Sql); } } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/DesensitizationTest_insert.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/DesensitizationTest_insert.java index 48601c1f11..d461a3cb97 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/DesensitizationTest_insert.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/DesensitizationTest_insert.java @@ -24,9 +24,9 @@ public class DesensitizationTest_insert extends TestCase { System.out.println("-------------------"); System.out.println(desens_Sql); - assertEquals("INSERT INTO T_126BF2439561E30E (supplier_id, supplier_name)\n" + + assertEquals("INSERT INTO T_2EBB0E6843F14AEE (supplier_id, supplier_name)\n" + "SELECT account_no, name\n" + - "FROM T_69BFC132C09344DE\n" + + "FROM T_0C9879D1E6FFA3BE\n" + "WHERE customer_id > ?;", desens_Sql); } } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/DesensitizationTest_update.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/DesensitizationTest_update.java index 47ad95c7fa..7d4eff48a9 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/DesensitizationTest_update.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/DesensitizationTest_update.java @@ -22,7 +22,7 @@ public class DesensitizationTest_update extends TestCase { System.out.println("-------------------"); System.out.println(desens_Sql); - assertEquals("UPDATE T_69BFC132C09344DE\n" + + assertEquals("UPDATE T_0C9879D1E6FFA3BE\n" + "SET last_name = ?\n" + "WHERE customer_id = ?;", desens_Sql); } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleMergeTest4.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleMergeTest4.java index 2d072b621a..328d4dd707 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleMergeTest4.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleMergeTest4.java @@ -28,7 +28,7 @@ import com.alibaba.druid.stat.TableStat; public class OracleMergeTest4 extends OracleTest { public void test_0() throws Exception { - String sql = "MERGE INTO \"ESCROW \". \"HT_TASK_TRADE_HISTORY_NEW \" SNA$ USING (SELECT \"CURRENT$ \". \"ID \", \"OUTERTAB$ \". \"GMT_MODIFIED \" \"GMT_MODIFIED \", \"OUTERTAB$ \". \"GMT_CREATE \" \"GMT_CREATE \", \"OUTERTAB$ \". \"TRADE_ID \" \"TRADE_ID \", \"OUTERTAB$ \". \"STATUS \" \"STATUS \", \"OUTERTAB$ \". \"OWNER \" \"OWNER \", \"OUTERTAB$ \". \"GMT_FETCH_TASK \" \"GMT_FETCH_TASK \", \"OUTERTAB$ \". \"GMT_FINISH_TASK \" \"GMT_FINISH_TASK \", \"OUTERTAB$ \". \"VERSION \" \"VERSION \", \"OUTERTAB$ \". \"RECORD_TYPE \" \"RECORD_TYPE \", \"OUTERTAB$ \". \"TASK_FLOW_LEVEL \" \"TASK_FLOW_LEVEL \", \"OUTERTAB$ \". \"DEAL_TYPE \" \"DEAL_TYPE \", \"OUTERTAB$ \". \"END_REASON \" \"END_REASON \", \"OUTERTAB$ \". \"TRANSIT_TIME \" \"TRANSIT_TIME \" FROM (SELECT /*+ NO_MERGE NO_MERGE(LL$) ROWID(MAS$) ORDERED USE_NL(MAS$) NO_INDEX(MAS$) PQ_DISTRIBUTE(MAS$,RANDOM,NONE) */ \"MAS$ \". \"ID \" \"ID \" FROM \"ALL_SUMDELTA \" \"LL$ \", \"ESCROW \". \"HT_TASK_TRADE_HISTORY \" \"MAS$ \" WHERE ((LL$.TABLEOBJ# = :1 AND LL$.TIMESTAMP > :2 AND \"MAS$ \".ROWID BETWEEN LL$.LOWROWID AND LL$.HIGHROWID))) CURRENT$, \"ESCROW \". \"HT_TASK_TRADE_HISTORY \" OUTERTAB$ WHERE CURRENT$. \"ID \" = OUTERTAB$. \"ID \") AS OF SNAPSHOT(:SCN) MAS$ ON (SNA$. \"ID \" = MAS$. \"ID \") WHEN MATCHED THEN UPDATE SET SNA$. \"ID \" = MAS$. \"ID \", SNA$. \"GMT_MODIFIED \" = MAS$. \"GMT_MODIFIED \", SNA$. \"GMT_CREATE \" = MAS$. \"GMT_CREATE \", SNA$. \"TRADE_ID \" = MAS$. \"TRADE_ID \", SNA$. \"STATUS \" = MAS$. \"STATUS \", SNA$. \"OWNER \" = MAS$. \"OWNER \", SNA$. \"GMT_FETCH_TASK \" = MAS$. \"GMT_FETCH_TASK \", SNA$. \"GMT_FINISH_TASK \" = MAS$. \"GMT_FINISH_TASK \", SNA$. \"VERSION \" = MAS$. \"VERSION \", SNA$. \"RECORD_TYPE \" = MAS$. \"RECORD_TYPE \", SNA$. \"TASK_FLOW_LEVEL \" = MAS$. \"TASK_FLOW_LEVEL \", SNA$. \"DEAL_TYPE \" = MAS$. \"DEAL_TYPE \", SNA$. \"END_REASON \" = MAS$. \"END_REASON \", SNA$. \"TRANSIT_TIME \" = MAS$. \"TRANSIT_TIME \" WHEN NOT MATCHED THEN INSERT ( \"ID \", \"GMT_MODIFIED \", \"GMT_CREATE \", \"TRADE_ID \", \"STATUS \", \"OWNER \", \"GMT_FETCH_TASK \", \"GMT_FINISH_TASK \", \"VERSION \", \"RECORD_TYPE \", \"TASK_FLOW_LEVEL \", \"DEAL_TYPE \", \"END_REASON \", \"TRANSIT_TIME \") VALUES (MAS$. \"ID \",MAS$. \"GMT_MODIFIED \",MAS$. \"GMT_CREATE \",MAS$. \"TRADE_ID \",MAS$. \"STATUS \",MAS$. \"OWNER \",MAS$. \"GMT_FETCH_TASK \",MAS$. \"GMT_FINISH_TASK \",MAS$. \"VERSION \",MAS$. \"RECORD_TYPE \",MAS$. \"TASK_FLOW_LEVEL \",MAS$. \"DEAL_TYPE \",MAS$. \"END_REASON \",MAS$. \"TRANSIT_TIME \")"; + String sql = "MERGE INTO \"ESCROW\". \"HT_TASK_TRADE_HISTORY_NEW \" SNA$ USING (SELECT \"CURRENT$ \". \"ID \", \"OUTERTAB$ \". \"GMT_MODIFIED \" \"GMT_MODIFIED \", \"OUTERTAB$ \". \"GMT_CREATE \" \"GMT_CREATE \", \"OUTERTAB$ \". \"TRADE_ID \" \"TRADE_ID \", \"OUTERTAB$ \". \"STATUS \" \"STATUS \", \"OUTERTAB$ \". \"OWNER \" \"OWNER \", \"OUTERTAB$ \". \"GMT_FETCH_TASK \" \"GMT_FETCH_TASK \", \"OUTERTAB$ \". \"GMT_FINISH_TASK \" \"GMT_FINISH_TASK \", \"OUTERTAB$ \". \"VERSION \" \"VERSION \", \"OUTERTAB$ \". \"RECORD_TYPE \" \"RECORD_TYPE \", \"OUTERTAB$ \". \"TASK_FLOW_LEVEL \" \"TASK_FLOW_LEVEL \", \"OUTERTAB$ \". \"DEAL_TYPE \" \"DEAL_TYPE \", \"OUTERTAB$ \". \"END_REASON \" \"END_REASON \", \"OUTERTAB$ \". \"TRANSIT_TIME \" \"TRANSIT_TIME \" FROM (SELECT /*+ NO_MERGE NO_MERGE(LL$) ROWID(MAS$) ORDERED USE_NL(MAS$) NO_INDEX(MAS$) PQ_DISTRIBUTE(MAS$,RANDOM,NONE) */ \"MAS$ \". \"ID \" \"ID \" FROM \"ALL_SUMDELTA\" \"LL$ \", \"ESCROW\". \"HT_TASK_TRADE_HISTORY\" \"MAS$ \" WHERE ((LL$.TABLEOBJ# = :1 AND LL$.TIMESTAMP > :2 AND \"MAS$ \".ROWID BETWEEN LL$.LOWROWID AND LL$.HIGHROWID))) CURRENT$, \"ESCROW\". \"HT_TASK_TRADE_HISTORY\" OUTERTAB$ WHERE CURRENT$. \"ID \" = OUTERTAB$. \"ID \") AS OF SNAPSHOT(:SCN) MAS$ ON (SNA$. \"ID \" = MAS$. \"ID \") WHEN MATCHED THEN UPDATE SET SNA$. \"ID \" = MAS$. \"ID \", SNA$. \"GMT_MODIFIED \" = MAS$. \"GMT_MODIFIED \", SNA$. \"GMT_CREATE \" = MAS$. \"GMT_CREATE \", SNA$. \"TRADE_ID \" = MAS$. \"TRADE_ID \", SNA$. \"STATUS \" = MAS$. \"STATUS \", SNA$. \"OWNER \" = MAS$. \"OWNER \", SNA$. \"GMT_FETCH_TASK \" = MAS$. \"GMT_FETCH_TASK \", SNA$. \"GMT_FINISH_TASK \" = MAS$. \"GMT_FINISH_TASK \", SNA$. \"VERSION \" = MAS$. \"VERSION \", SNA$. \"RECORD_TYPE \" = MAS$. \"RECORD_TYPE \", SNA$. \"TASK_FLOW_LEVEL \" = MAS$. \"TASK_FLOW_LEVEL \", SNA$. \"DEAL_TYPE \" = MAS$. \"DEAL_TYPE \", SNA$. \"END_REASON \" = MAS$. \"END_REASON \", SNA$. \"TRANSIT_TIME \" = MAS$. \"TRANSIT_TIME \" WHEN NOT MATCHED THEN INSERT ( \"ID \", \"GMT_MODIFIED \", \"GMT_CREATE \", \"TRADE_ID \", \"STATUS \", \"OWNER \", \"GMT_FETCH_TASK \", \"GMT_FINISH_TASK \", \"VERSION \", \"RECORD_TYPE \", \"TASK_FLOW_LEVEL \", \"DEAL_TYPE \", \"END_REASON \", \"TRANSIT_TIME \") VALUES (MAS$. \"ID \",MAS$. \"GMT_MODIFIED \",MAS$. \"GMT_CREATE \",MAS$. \"TRADE_ID \",MAS$. \"STATUS \",MAS$. \"OWNER \",MAS$. \"GMT_FETCH_TASK \",MAS$. \"GMT_FINISH_TASK \",MAS$. \"VERSION \",MAS$. \"RECORD_TYPE \",MAS$. \"TASK_FLOW_LEVEL \",MAS$. \"DEAL_TYPE \",MAS$. \"END_REASON \",MAS$. \"TRANSIT_TIME \")"; OracleStatementParser parser = new OracleStatementParser(sql); List statementList = parser.parseStatementList(); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleTruncateTableTest.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleTruncateTableTest.java index 4bd22786bc..76854a95b1 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleTruncateTableTest.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleTruncateTableTest.java @@ -49,7 +49,10 @@ public class OracleTruncateTableTest extends OracleTest { Assert.assertEquals(1, visitor.getTables().size()); - Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("ESCROW.HT_TASK_TRADE_HISTORY_NEW"))); + Assert.assertTrue(visitor + .getTables() + .containsKey( + new TableStat.Name("ESCROW.HT_TASK_TRADE_HISTORY_NEW"))); Assert.assertEquals(0, visitor.getColumns().size()); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleUpdateTest5_encoding_error.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleUpdateTest5_encoding_error.java new file mode 100644 index 0000000000..ef875b8654 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/OracleUpdateTest5_encoding_error.java @@ -0,0 +1,67 @@ +/* + * Copyright 1999-2017 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.bvt.sql.oracle; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; +import com.alibaba.druid.util.JdbcConstants; + +import java.util.List; + +public class OracleUpdateTest5_encoding_error extends OracleTest { + + public void test_0() throws Exception { + String sql = "update x1_use_agent t2 set t2.start_time =to_date((select to_char(sysdate,'yyyy-mm-dd HH24:mi:ss') from dual), 'yyyy-mm-dd HH24:mi:ss'), t2.end_time=to_date((select to_char(sysdate + interval '1' year ,'yyyy-mm-dd HH24:mi:ss') from dual), 'yyyy-mm-dd HH24:mi:ss') where t2.attr2 ='ZB201708311440560'"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + print(statementList); + + assertEquals(1, statementList.size()); + + assertEquals("UPDATE x1_use_agent t2\n" + + "SET t2.start_time = to_date((\n" + + "\tSELECT to_char(SYSDATE, 'yyyy-mm-dd HH24:mi:ss')\n" + + "\tFROM dual\n" + + "), 'yyyy-mm-dd HH24:mi:ss'), t2.end_time = to_date((\n" + + "\tSELECT to_char(SYSDATE + INTERVAL '1' YEAR, 'yyyy-mm-dd HH24:mi:ss')\n" + + "\tFROM dual\n" + + "), 'yyyy-mm-dd HH24:mi:ss')\n" + + "WHERE t2.attr2 = 'ZB201708311440560'",// + SQLUtils.toSQLString(stmt, JdbcConstants.ORACLE)); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + stmt.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); +// System.out.println("coditions : " + visitor.getConditions()); +// System.out.println("relationships : " + visitor.getRelationships()); + + assertEquals(1, visitor.getTables().size()); + assertEquals(3, visitor.getColumns().size()); + + assertTrue(visitor.getTables().containsKey(new TableStat.Name("x1_use_agent"))); + + assertTrue(visitor.getColumns().contains(new TableStat.Column("x1_use_agent", "start_time"))); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/insert/OracleInsertTest15.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/insert/OracleInsertTest15.java index af2b5a4c7b..add6bbdeb6 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/insert/OracleInsertTest15.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/insert/OracleInsertTest15.java @@ -59,7 +59,10 @@ public class OracleInsertTest15 extends OracleTest { Assert.assertEquals(1, visitor.getTables().size()); Assert.assertEquals(0, visitor.getColumns().size()); - Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("employees@remote"))); + Assert.assertTrue(visitor + .getTables() + .containsKey( + new TableStat.Name("employees@remote"))); // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("employees", "salary"))); } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/insert/OracleInsertTest21_encoding_error.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/insert/OracleInsertTest21_encoding_error.java new file mode 100644 index 0000000000..ef4058735e --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/insert/OracleInsertTest21_encoding_error.java @@ -0,0 +1,74 @@ +/* + * Copyright 1999-2017 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.bvt.sql.oracle.insert; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; +import com.alibaba.druid.util.JdbcConstants; + +import java.util.List; + +public class OracleInsertTest21_encoding_error extends OracleTest { + + public void test_0() throws Exception { + String sql = "INSERT INTO x1_use_agent (ID, company_name, company_id, amount, start_time, end_time, is_deleted,attr2) VALUES (seq_fee_use_agent.nextval,'\n" + + "w[���р Pl�','19929',(select c.FEE_AGENT from cfg_fee_agent c), to_date((select to_char(sysdate,'yyyy-mm-dd HH24:mi:ss') from dual), 'yyyy-mm-dd HH24:mi:ss'),to_date((select to_char(sysdate + interval '1' year ,'yyyy-mm-dd HH24:mi:ss') from dual), 'yyyy-mm-dd HH24:mi:ss'),'0','ZB20170831142805148890')"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + print(statementList); + + assertEquals(1, statementList.size()); + + assertEquals("INSERT INTO x1_use_agent\n" + + "\t(ID, company_name, company_id, amount, start_time\n" + + "\t, end_time, is_deleted, attr2)\n" + + "VALUES (seq_fee_use_agent.NEXTVAL, '\n" + + "w[���р Pl�', '19929', \n" + + "\t(SELECT c.FEE_AGENT\n" + + "\tFROM cfg_fee_agent c)\n" + + "\t, to_date((\n" + + "\t\tSELECT to_char(SYSDATE, 'yyyy-mm-dd HH24:mi:ss')\n" + + "\t\tFROM dual\n" + + "\t), 'yyyy-mm-dd HH24:mi:ss')\n" + + "\t, to_date((\n" + + "\t\tSELECT to_char(SYSDATE + INTERVAL '1' YEAR, 'yyyy-mm-dd HH24:mi:ss')\n" + + "\t\tFROM dual\n" + + "\t), 'yyyy-mm-dd HH24:mi:ss'), '0', 'ZB20170831142805148890')",// + SQLUtils.toSQLString(stmt, JdbcConstants.ORACLE)); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + stmt.accept(visitor); + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); +// System.out.println("coditions : " + visitor.getConditions()); +// System.out.println("relationships : " + visitor.getRelationships()); + + assertEquals(1, visitor.getTables().size()); + assertEquals(8, visitor.getColumns().size()); + + assertTrue(visitor.getTables().containsKey(new TableStat.Name("x1_use_agent"))); + + assertTrue(visitor.getColumns().contains(new TableStat.Column("x1_use_agent", "ID"))); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest24.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest24.java index 4e81cde2f0..223590bffd 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest24.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest24.java @@ -30,7 +30,7 @@ public class OracleSelectTest24 extends OracleTest { public void test_0() throws Exception { String sql = // - "select /*+ no_parallel_index(t, \"HT_TASK_TRADE_HIS_GOR_IND \") dbms_stats cursor_sharing_exact use_weak_name_resl dynamic_sampling(0) no_monitoring no_expand index_ffs(t, \"HT_TASK_TRADE_HIS_GOR_IND \") */ count(*) as nrw,count(distinct sys_op_lbid(196675,'L',t.rowid)) as nlb,count(distinct hextoraw(sys_op_descend( \"GMT_MODIFIED \")||sys_op_descend( \"OWNER \")||sys_op_descend( \"RECORD_TYPE \"))) as ndk,sys_op_countchg(substrb(t.rowid,1,15),1) as clf from \"ESCROW \". \"HT_TASK_TRADE_HISTORY \" sample block ( 34.6426417370,1) t where \"GMT_MODIFIED \" is not null or \"OWNER \" is not null or \"RECORD_TYPE \" is not null"; // + "select /*+ no_parallel_index(t, \"HT_TASK_TRADE_HIS_GOR_IND \") dbms_stats cursor_sharing_exact use_weak_name_resl dynamic_sampling(0) no_monitoring no_expand index_ffs(t, \"HT_TASK_TRADE_HIS_GOR_IND \") */ count(*) as nrw,count(distinct sys_op_lbid(196675,'L',t.rowid)) as nlb,count(distinct hextoraw(sys_op_descend( \"GMT_MODIFIED \")||sys_op_descend( \"OWNER \")||sys_op_descend( \"RECORD_TYPE \"))) as ndk,sys_op_countchg(substrb(t.rowid,1,15),1) as clf from \"ESCROW\". \"HT_TASK_TRADE_HISTORY\" sample block ( 34.6426417370,1) t where \"GMT_MODIFIED \" is not null or \"OWNER \" is not null or \"RECORD_TYPE \" is not null"; // OracleStatementParser parser = new OracleStatementParser(sql); List statementList = parser.parseStatementList(); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest28.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest28.java index f3ec845852..98f057a650 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest28.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest28.java @@ -29,7 +29,7 @@ public class OracleSelectTest28 extends OracleTest { public void test_0() throws Exception { String sql = // - "SELECT /*+ ORDERED USE_NL ( \"A1 \") USE_NL ( \"A2 \") USE_NL ( \"A3 \") */ \"A3 \". \"AP_PAY_TIME \", \"A2 \". \"ORDER_ID \", \"A3 \". \"AP_PAY_AMT \", \"A1 \". \"COUNTRY \" FROM \"ESCROW \". \"TRADE_PAY \" \"A3 \", \"ESCROW \". \"ESCROW_TRADE \" \"A2 \", \"ESCROW \". \"BUSINESS_ORDER \" \"A1 \" WHERE \"A3 \". \"TRADE_ID \"= \"A2 \". \"ID \" AND \"A1 \". \"ID \"(+)=TO_NUMBER( \"A2 \". \"OUT_ORDER_ID \") AND \"A2 \". \"ORDER_FROM \"='wholesale_order' AND \"A3 \". \"AP_PAY_TIME \">=:1-.003819444444444444444444444444444444444444 AND \"A3 \". \"AP_PAY_TIME \">=TRUNC(:2)"; + "SELECT /*+ ORDERED USE_NL ( \"A1 \") USE_NL ( \"A2 \") USE_NL ( \"A3 \") */ \"A3 \". \"AP_PAY_TIME \", \"A2 \". \"ORDER_ID \", \"A3 \". \"AP_PAY_AMT \", \"A1 \". \"COUNTRY \" FROM \"ESCROW\". \"TRADE_PAY\" \"A3 \", \"ESCROW\". \"ESCROW_TRADE\" \"A2 \", \"ESCROW\". \"BUSINESS_ORDER\" \"A1 \" WHERE \"A3 \". \"TRADE_ID \"= \"A2 \". \"ID \" AND \"A1 \". \"ID \"(+)=TO_NUMBER( \"A2 \". \"OUT_ORDER_ID \") AND \"A2 \". \"ORDER_FROM \"='wholesale_order' AND \"A3 \". \"AP_PAY_TIME \">=:1-.003819444444444444444444444444444444444444 AND \"A3 \". \"AP_PAY_TIME \">=TRUNC(:2)"; OracleStatementParser parser = new OracleStatementParser(sql); List statementList = parser.parseStatementList(); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest80.java b/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest80.java new file mode 100644 index 0000000000..477fb35207 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest80.java @@ -0,0 +1,67 @@ +/* + * Copyright 1999-2017 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.druid.bvt.sql.oracle.select; + +import com.alibaba.druid.sql.OracleTest; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.oracle.parser.OracleStatementParser; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleSchemaStatVisitor; +import org.junit.Assert; + +import java.util.List; + +public class OracleSelectTest80 extends OracleTest { + + public void test_0() throws Exception { + String sql = // + "select * from t"; // + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement stmt = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + stmt.accept(visitor); + + { + String text = SQLUtils.toOracleString(stmt); + + assertEquals("SELECT *\n" + + "FROM t", text); + } + + System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); + System.out.println("coditions : " + visitor.getConditions()); + System.out.println("relationships : " + visitor.getRelationships()); + System.out.println("orderBy : " + visitor.getOrderByColumns()); + + assertEquals(1, visitor.getTables().size()); + assertEquals(1, visitor.getColumns().size()); + assertEquals(0, visitor.getConditions().size()); + assertEquals(0, visitor.getRelationships().size()); + assertEquals(0, visitor.getOrderByColumns().size()); + + + // Assert.assertTrue(visitor.getColumns().contains(new TableStat.Column("acduser.vw_acd_info", "xzqh"))); + + // Assert.assertTrue(visitor.getOrderByColumns().contains(new TableStat.Column("employees", "last_name"))); + } +} diff --git a/src/test/java/com/alibaba/druid/sql/oracle/demo/OracleResourceTest2.java b/src/test/java/com/alibaba/druid/sql/oracle/demo/OracleResourceTest2.java index 2d9f3d8aa9..fe876724bb 100644 --- a/src/test/java/com/alibaba/druid/sql/oracle/demo/OracleResourceTest2.java +++ b/src/test/java/com/alibaba/druid/sql/oracle/demo/OracleResourceTest2.java @@ -30,7 +30,7 @@ import java.util.List; public class OracleResourceTest2 extends OracleTest { public void test_0() throws Exception { - File file = new File("/Users/wenshao/Downloads/Procedures.sql"); + File file = new File("/Users/wenshao/Downloads/ff.sql"); String sql = FileUtils.readFileToString(file);