diff --git a/pom.xml b/pom.xml index ca33a00303..41766f7da4 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ --> com.alibaba druid - 1.0.28-SNAPSHOT + 1.0.28 jar druid diff --git a/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java index 8519865ad7..41d802353b 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java @@ -1114,6 +1114,10 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements } public void setDriverClassName(String driverClass) { + if (driverClass != null && driverClass.length() > 256) { + throw new IllegalArgumentException("driverClassName length > 256."); + } + if (inited) { if (StringUtils.equals(this.driverClass, driverClass)) { return; diff --git a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java index 81ad6dc17a..f83d895a28 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidDataSource.java @@ -1031,7 +1031,8 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat if (realDriverClassName.equals(JdbcConstants.MYSQL_DRIVER) // || realDriverClassName.equals(JdbcConstants.MYSQL_DRIVER_6)) { this.exceptionSorter = new MySqlExceptionSorter(); - } else if (realDriverClassName.equals(JdbcConstants.ORACLE_DRIVER)) { + } else if (realDriverClassName.equals(JdbcConstants.ORACLE_DRIVER) + || realDriverClassName.equals(JdbcConstants.ORACLE_DRIVER2)) { this.exceptionSorter = new OracleExceptionSorter(); } else if (realDriverClassName.equals("com.informix.jdbc.IfxDriver")) { this.exceptionSorter = new InformixExceptionSorter(); diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLInSubQueryExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLInSubQueryExpr.java index 18e5a82c4b..cdce963f35 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLInSubQueryExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLInSubQueryExpr.java @@ -47,6 +47,9 @@ public class SQLInSubQueryExpr extends SQLExprImpl implements Serializable { } public void setExpr(SQLExpr expr) { + if (expr != null) { + expr.setParent(this); + } this.expr = expr; } diff --git a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateViewStatement.java b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateViewStatement.java index 8baa8d8830..a4e081bc89 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateViewStatement.java +++ b/src/main/java/com/alibaba/druid/sql/ast/statement/SQLCreateViewStatement.java @@ -33,6 +33,10 @@ public class SQLCreateViewStatement extends SQLStatementImpl implements SQLDDLSt protected SQLSelect subQuery; protected boolean ifNotExists = false; + protected String algorithm; + protected SQLName definer; + protected String sqlSecurity; + protected final List columns = new ArrayList(); private Level with; @@ -109,6 +113,33 @@ public class SQLCreateViewStatement extends SQLStatementImpl implements SQLDDLSt this.comment = comment; } + public String getAlgorithm() { + return algorithm; + } + + public void setAlgorithm(String algorithm) { + this.algorithm = algorithm; + } + + public SQLName getDefiner() { + return definer; + } + + public void setDefiner(SQLName definer) { + if (definer != null) { + definer.setParent(this); + } + this.definer = definer; + } + + public String getSqlSecurity() { + return sqlSecurity; + } + + public void setSqlSecurity(String sqlSecurity) { + this.sqlSecurity = sqlSecurity; + } + public void output(StringBuffer buf) { buf.append("CREATE VIEW "); this.name.output(buf); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java index 353945fcde..00b24a26c7 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/parser/MySqlStatementParser.java @@ -37,55 +37,8 @@ import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr; import com.alibaba.druid.sql.ast.expr.SQLNCharExpr; import com.alibaba.druid.sql.ast.expr.SQLQueryExpr; import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; -import com.alibaba.druid.sql.ast.statement.SQLAlterDatabaseStatement; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddColumn; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddConstraint; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddIndex; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableAddPartition; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableAnalyzePartition; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableCheckPartition; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableCoalescePartition; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableConvertCharSet; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableDisableConstraint; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableDisableKeys; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableDiscardPartition; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropColumnItem; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropConstraint; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropForeignKey; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropIndex; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropKey; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropPartition; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableDropPrimaryKey; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableEnableConstraint; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableEnableKeys; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableImportPartition; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableOptimizePartition; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableReOrganizePartition; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableRebuildPartition; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableRepairPartition; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement; -import com.alibaba.druid.sql.ast.statement.SQLAlterTableTruncatePartition; -import com.alibaba.druid.sql.ast.statement.SQLBlockStatement; -import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; -import com.alibaba.druid.sql.ast.statement.SQLCreateDatabaseStatement; -import com.alibaba.druid.sql.ast.statement.SQLCreateIndexStatement; -import com.alibaba.druid.sql.ast.statement.SQLCreateProcedureStatement; -import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; -import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; -import com.alibaba.druid.sql.ast.statement.SQLIfStatement; -import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; +import com.alibaba.druid.sql.ast.statement.*; import com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause; -import com.alibaba.druid.sql.ast.statement.SQLLoopStatement; -import com.alibaba.druid.sql.ast.statement.SQLPrimaryKey; -import com.alibaba.druid.sql.ast.statement.SQLSelect; -import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem; -import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; -import com.alibaba.druid.sql.ast.statement.SQLSetStatement; -import com.alibaba.druid.sql.ast.statement.SQLShowTablesStatement; -import com.alibaba.druid.sql.ast.statement.SQLTableSource; -import com.alibaba.druid.sql.ast.statement.SQLUnique; -import com.alibaba.druid.sql.ast.statement.SQLUpdateSetItem; -import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; import com.alibaba.druid.sql.dialect.mysql.ast.MysqlForeignKey; import com.alibaba.druid.sql.dialect.mysql.ast.clause.ConditionValue; import com.alibaba.druid.sql.dialect.mysql.ast.clause.ConditionValue.ConditionType; @@ -179,7 +132,6 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowTableStatusSta import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowTriggersStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowVariantsStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlShowWarningsStatement; -import com.alibaba.druid.sql.ast.statement.SQLStartTransactionStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUnlockTablesStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MysqlDeallocatePrepareStatement; @@ -376,7 +328,8 @@ public class MySqlStatementParser extends SQLStatementParser { return parseCreateUser(); } - if (lexer.token() == Token.VIEW) { + if (lexer.token() == Token.VIEW + || identifierEquals("ALGORITHM")) { if (replace) { lexer.reset(markBp, markChar, Token.CREATE); } @@ -398,7 +351,7 @@ public class MySqlStatementParser extends SQLStatementParser { return parseCreateProcedure(); } - throw new ParserException("TODO " + lexer.token()); + throw new ParserException("TODO " + lexer.info()); } public SQLStatement parseCreateIndex(boolean acceptCreate) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java index 80a6afd6d1..5c46267177 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlOutputVisitor.java @@ -681,20 +681,8 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV int index = x.getIndex(); if (index >= 0 && index < parametersSize) { - Object param = this.getParameters().get(index); - if (param instanceof Collection && x.getParent() instanceof SQLInListExpr) { - boolean first = true; - for (Object item : (Collection) param) { - if (!first) { - print0(", "); - } - printParameter(item); - first = false; - } - } else { - printParameter(param); - } - return false; + + return super.visit(x); } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsInsertStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsInsertStatement.java index 5e20446289..bca8af50ff 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsInsertStatement.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsInsertStatement.java @@ -21,13 +21,14 @@ import java.util.List; import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.SQLStatementImpl; import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; +import com.alibaba.druid.sql.ast.statement.SQLTableSource; import com.alibaba.druid.sql.dialect.odps.visitor.OdpsASTVisitor; import com.alibaba.druid.sql.visitor.SQLASTVisitor; import com.alibaba.druid.util.JdbcConstants; public class OdpsInsertStatement extends SQLStatementImpl implements SQLStatement { - private SQLSubqueryTableSource from; + private SQLTableSource from; private List items = new ArrayList(); @@ -35,11 +36,11 @@ public class OdpsInsertStatement extends SQLStatementImpl implements SQLStatemen super (JdbcConstants.ODPS); } - public void setFrom(SQLSubqueryTableSource from) { + public void setFrom(SQLTableSource from) { this.from = from; } - public SQLSubqueryTableSource getFrom() { + public SQLTableSource getFrom() { return from; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsValuesTableSource.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsValuesTableSource.java new file mode 100644 index 0000000000..86311cbc06 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/ast/OdpsValuesTableSource.java @@ -0,0 +1,42 @@ +package com.alibaba.druid.sql.dialect.odps.ast; + +import com.alibaba.druid.sql.ast.SQLName; +import com.alibaba.druid.sql.ast.expr.SQLListExpr; +import com.alibaba.druid.sql.ast.statement.SQLTableSource; +import com.alibaba.druid.sql.ast.statement.SQLTableSourceImpl; +import com.alibaba.druid.sql.dialect.odps.ast.OdpsObject; +import com.alibaba.druid.sql.dialect.odps.visitor.OdpsASTVisitor; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by wenshao on 23/02/2017. + */ +public class OdpsValuesTableSource extends SQLTableSourceImpl implements OdpsObject { + private List values = new ArrayList(); + private List columns = new ArrayList(); + + @Override + protected void accept0(SQLASTVisitor visitor) { + accept0((OdpsASTVisitor) visitor); + } + + public List getValues() { + return values; + } + + public List getColumns() { + return columns; + } + + @Override + public void accept0(OdpsASTVisitor visitor) { + if (visitor.visit(this)) { + acceptChild(visitor, values); + acceptChild(visitor, columns); + } + visitor.endVisit(this); + } +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsSelectParser.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsSelectParser.java index 2c74cd3578..88a596e0b1 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsSelectParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsSelectParser.java @@ -19,12 +19,14 @@ import com.alibaba.druid.sql.ast.SQLExpr; import com.alibaba.druid.sql.ast.SQLLimit; import com.alibaba.druid.sql.ast.SQLOrderingSpecification; import com.alibaba.druid.sql.ast.SQLSetQuantifier; +import com.alibaba.druid.sql.ast.expr.SQLListExpr; import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem; import com.alibaba.druid.sql.ast.statement.SQLSelectQuery; import com.alibaba.druid.sql.ast.statement.SQLTableSource; import com.alibaba.druid.sql.dialect.odps.ast.OdpsLateralViewTableSource; import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock; +import com.alibaba.druid.sql.dialect.odps.ast.OdpsValuesTableSource; import com.alibaba.druid.sql.parser.SQLExprParser; import com.alibaba.druid.sql.parser.SQLSelectParser; import com.alibaba.druid.sql.parser.Token; @@ -123,6 +125,41 @@ public class OdpsSelectParser extends SQLSelectParser { return queryRest(queryBlock); } + + public SQLTableSource parseTableSource() { + if (lexer.token() == Token.VALUES) { + lexer.nextToken(); + OdpsValuesTableSource tableSource = new OdpsValuesTableSource(); + + for (;;) { + accept(Token.LPAREN); + SQLListExpr listExpr = new SQLListExpr(); + this.exprParser.exprList(listExpr.getItems(), listExpr); + accept(Token.RPAREN); + + listExpr.setParent(tableSource); + + tableSource.getValues().add(listExpr); + + if (lexer.token() == Token.COMMA) { + lexer.nextToken(); + continue; + } + break; + } + + String alias = this.as(); + tableSource.setAlias(alias); + + accept(Token.LPAREN); + this.exprParser.names(tableSource.getColumns(), tableSource); + accept(Token.RPAREN); + + return tableSource; + } + + return super.parseTableSource(); + } protected SQLTableSource parseTableSourceRest(SQLTableSource tableSource) { tableSource = super.parseTableSourceRest(tableSource); diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java index d7b1e29570..dedca4506d 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/parser/OdpsStatementParser.java @@ -226,19 +226,26 @@ public class OdpsStatementParser extends SQLStatementParser { if (lexer.token() == Token.FROM) { lexer.nextToken(); - accept(Token.LPAREN); - SQLSelectParser selectParser = createSQLSelectParser(); - SQLSelect select = selectParser.select(); + if (lexer.token() == Token.IDENTIFIER) { + SQLName tableName = this.exprParser.name(); + SQLExprTableSource from = new SQLExprTableSource(tableName); + stmt.setFrom(from); + } else { + accept(Token.LPAREN); - accept(Token.RPAREN); + SQLSelectParser selectParser = createSQLSelectParser(); + SQLSelect select = selectParser.select(); - String alias = lexer.stringVal(); - accept(Token.IDENTIFIER); + accept(Token.RPAREN); - SQLSubqueryTableSource from = new SQLSubqueryTableSource(select, alias); + String alias = lexer.stringVal(); + accept(Token.IDENTIFIER); - stmt.setFrom(from); + SQLSubqueryTableSource from = new SQLSubqueryTableSource(select, alias); + + stmt.setFrom(from); + } } for (;;) { diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitor.java index e054fdbefb..8301f1e0ef 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitor.java @@ -15,24 +15,7 @@ */ package com.alibaba.druid.sql.dialect.odps.visitor; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsAddStatisticStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsAnalyzeTableStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsCreateTableStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsDescStmt; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsGrantStmt; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsert; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsertStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsLateralViewTableSource; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsListStmt; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsReadStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsRemoveStatisticStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsSetLabelStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowGrantsStmt; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowPartitionsStmt; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowStatisticStmt; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsStatisticClause; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsUDTFSQLSelectItem; +import com.alibaba.druid.sql.dialect.odps.ast.*; import com.alibaba.druid.sql.visitor.SQLASTVisitor; public interface OdpsASTVisitor extends SQLASTVisitor { @@ -128,4 +111,8 @@ public interface OdpsASTVisitor extends SQLASTVisitor { void endVisit(OdpsLateralViewTableSource x); boolean visit(OdpsLateralViewTableSource x); + + void endVisit(OdpsValuesTableSource x); + + boolean visit(OdpsValuesTableSource x); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitorAdapter.java index 01301b60d6..0a859c84ed 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsASTVisitorAdapter.java @@ -15,24 +15,7 @@ */ package com.alibaba.druid.sql.dialect.odps.visitor; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsAddStatisticStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsAnalyzeTableStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsCreateTableStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsDescStmt; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsGrantStmt; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsert; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsertStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsLateralViewTableSource; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsListStmt; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsReadStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsRemoveStatisticStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsSetLabelStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowGrantsStmt; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowPartitionsStmt; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowStatisticStmt; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsStatisticClause; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsUDTFSQLSelectItem; +import com.alibaba.druid.sql.dialect.odps.ast.*; import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter; @@ -268,4 +251,13 @@ public class OdpsASTVisitorAdapter extends SQLASTVisitorAdapter implements OdpsA return true; } + @Override + public void endVisit(OdpsValuesTableSource x) { + + } + + @Override + public boolean visit(OdpsValuesTableSource x) { + return true; + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java index e96efc145b..ac355472d8 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/odps/visitor/OdpsOutputVisitor.java @@ -27,32 +27,9 @@ import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLCaseExpr; import com.alibaba.druid.sql.ast.expr.SQLCharExpr; import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr; -import com.alibaba.druid.sql.ast.statement.SQLAssignItem; -import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; -import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; -import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource; +import com.alibaba.druid.sql.ast.statement.*; import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource.JoinType; -import com.alibaba.druid.sql.ast.statement.SQLSelectItem; -import com.alibaba.druid.sql.ast.statement.SQLSubqueryTableSource; -import com.alibaba.druid.sql.ast.statement.SQLTableElement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsAddStatisticStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsAnalyzeTableStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsCreateTableStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsDescStmt; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsGrantStmt; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsert; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsertStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsLateralViewTableSource; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsListStmt; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsReadStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsRemoveStatisticStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsSetLabelStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowGrantsStmt; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowPartitionsStmt; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowStatisticStmt; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsStatisticClause; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsUDTFSQLSelectItem; +import com.alibaba.druid.sql.dialect.odps.ast.*; import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; import com.alibaba.druid.util.JdbcConstants; @@ -194,15 +171,22 @@ public class OdpsOutputVisitor extends SQLASTOutputVisitor implements OdpsASTVis @Override public boolean visit(OdpsInsertStatement x) { + SQLTableSource from = x.getFrom(); if (x.getFrom() != null) { - print0(ucase ? "FROM (" : "from ("); - incrementIndent(); - println(); - x.getFrom().getSelect().accept(this); - decrementIndent(); - println(); - print0(") "); - print0(x.getFrom().getAlias()); + if (from instanceof SQLSubqueryTableSource) { + SQLSelect select = ((SQLSubqueryTableSource) from).getSelect(); + print0(ucase ? "FROM (" : "from ("); + incrementIndent(); + println(); + select.accept(this); + decrementIndent(); + println(); + print0(") "); + print0(x.getFrom().getAlias()); + } else { + print0(ucase ? "FROM " : "from "); + from.accept(this); + } println(); } @@ -910,4 +894,23 @@ public class OdpsOutputVisitor extends SQLASTOutputVisitor implements OdpsASTVis return false; } + + @Override + public void endVisit(OdpsValuesTableSource x) { + + } + + @Override + public boolean visit(OdpsValuesTableSource x) { + print0(ucase ? "VALUES " : "values "); + printAndAccept(x.getValues(), ", "); + + print(' '); + print0(x.getAlias()); + print0(" ("); + printAndAccept(x.getColumns(), ", "); + print(')'); + + 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 96fc53f955..6f188159ca 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 @@ -15,28 +15,14 @@ */ package com.alibaba.druid.sql.dialect.odps.visitor; -import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement; -import com.alibaba.druid.sql.ast.statement.SQLGrantStatement; -import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsAddStatisticStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsAnalyzeTableStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsCreateTableStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsDescStmt; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsGrantStmt; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsert; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsInsertStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsLateralViewTableSource; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsListStmt; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsReadStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsRemoveStatisticStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsSelectQueryBlock; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsSetLabelStatement; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowGrantsStmt; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowPartitionsStmt; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsShowStatisticStmt; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsStatisticClause; -import com.alibaba.druid.sql.dialect.odps.ast.OdpsUDTFSQLSelectItem; +import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLName; +import com.alibaba.druid.sql.ast.statement.*; +import com.alibaba.druid.sql.dialect.odps.ast.*; import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; + +import java.util.Map; public class OdpsSchemaStatVisitor extends SchemaStatVisitor implements OdpsASTVisitor { @@ -57,7 +43,7 @@ public class OdpsSchemaStatVisitor extends SchemaStatVisitor implements OdpsASTV @Override public boolean visit(OdpsInsertStatement x) { - return false; + return true; } @Override @@ -67,6 +53,31 @@ public class OdpsSchemaStatVisitor extends SchemaStatVisitor implements OdpsASTV @Override public boolean visit(OdpsInsert x) { + setMode(x, TableStat.Mode.Insert); + + setAliasMap(); + + SQLExprTableSource tableSource = x.getTableSource(); + SQLExpr tableName = tableSource.getExpr(); + + if (tableName instanceof SQLName) { + String ident = ((SQLName) tableName).toString(); + setCurrentTable(ident); + + TableStat stat = getTableStat(ident); + stat.incrementInsertCount(); + + Map aliasMap = getAliasMap(); + putAliasMap(aliasMap, tableSource.getAlias(), ident); + putAliasMap(aliasMap, ident, ident); + } + + for (SQLAssignItem partition : x.getPartitions()) { + partition.accept(this); + } + + accept(x.getQuery()); + return false; } @@ -272,4 +283,19 @@ public class OdpsSchemaStatVisitor extends SchemaStatVisitor implements OdpsASTV public boolean visit(OdpsLateralViewTableSource x) { return true; } + + @Override + public void endVisit(OdpsValuesTableSource x) { + + } + + @Override + public boolean visit(OdpsValuesTableSource x) { + Map aliasMap = getAliasMap(); + if (aliasMap != null && x.getAlias() != null) { + putAliasMap(aliasMap, x.getAlias(), null); + addSubQuery(x.getAlias(), x); + } + return false; + } } diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java index 159d893081..efce85b0ac 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLStatementParser.java @@ -1927,6 +1927,30 @@ public class SQLStatementParser extends SQLParser { createView.setOrReplace(true); } + if (identifierEquals("ALGORITHM")) { + lexer.nextToken(); + accept(Token.EQ); + String algorithm = lexer.stringVal(); + createView.setAlgorithm(algorithm); + lexer.nextToken(); + } + + if (identifierEquals("DEFINER")) { + lexer.nextToken(); + accept(Token.EQ); + SQLName definer = this.exprParser.name(); + createView.setDefiner(definer); + lexer.nextToken(); + } + + if (identifierEquals("SQL")) { + lexer.nextToken(); + acceptIdentifier("SECURITY"); + String sqlSecurity = lexer.stringVal(); + createView.setSqlSecurity(sqlSecurity); + lexer.nextToken(); + } + this.accept(Token.VIEW); if (lexer.token() == Token.IF || identifierEquals("IF")) { diff --git a/src/main/java/com/alibaba/druid/sql/parser/Token.java b/src/main/java/com/alibaba/druid/sql/parser/Token.java index e1390c39bc..bcefc7cc6e 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/Token.java +++ b/src/main/java/com/alibaba/druid/sql/parser/Token.java @@ -306,7 +306,7 @@ public enum Token { TILDE_STAR("~*"), TILDE_EQ("~="), QUES("?"), - QUESQUES("??"), + QUESQUES("??"), QUESBAR("?|"), QUESAMP("?&"), COLON(":"), diff --git a/src/main/java/com/alibaba/druid/sql/visitor/ExportParameterVisitorUtils.java b/src/main/java/com/alibaba/druid/sql/visitor/ExportParameterVisitorUtils.java index f3faebbfd2..55debe4a88 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/ExportParameterVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/ExportParameterVisitorUtils.java @@ -15,9 +15,11 @@ */ package com.alibaba.druid.sql.visitor; +import java.util.ArrayList; import java.util.List; import com.alibaba.druid.sql.ast.SQLExpr; +import com.alibaba.druid.sql.ast.SQLObject; import com.alibaba.druid.sql.ast.expr.SQLBetweenExpr; import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; import com.alibaba.druid.sql.ast.expr.SQLBooleanExpr; @@ -86,21 +88,46 @@ public final class ExportParameterVisitorUtils { } public static SQLExpr exportParameter(final List parameters, final SQLExpr param) { + Object value = null; + boolean replace = false; + if (param instanceof SQLCharExpr) { - Object value = ((SQLCharExpr) param).getText(); - parameters.add(value); - return new SQLVariantRefExpr("?"); + value = ((SQLCharExpr) param).getText(); + replace = true; } if (param instanceof SQLBooleanExpr) { - Object value = ((SQLBooleanExpr) param).getValue(); - parameters.add(value); - return new SQLVariantRefExpr("?"); + value = ((SQLBooleanExpr) param).getValue(); + replace = true; } if (param instanceof SQLNumericLiteralExpr) { - Object value = ((SQLNumericLiteralExpr) param).getNumber(); + value = ((SQLNumericLiteralExpr) param).getNumber(); + replace = true; + } + + if (replace) { + SQLObject parent = param.getParent(); + if (parent != null) { + List mergedList = (List) parent.getAttribute(ParameterizedOutputVisitorUtils.ATTR_MERGED); + if (mergedList != null) { + List mergedListParams = new ArrayList(mergedList.size() + 1); + for (int i = 0; i < mergedList.size(); ++i) { + SQLObject item = mergedList.get(i); + if (item instanceof SQLBinaryOpExpr) { + SQLBinaryOpExpr binaryOpItem = (SQLBinaryOpExpr) item; + exportParameter(mergedListParams, binaryOpItem.getRight()); + } + } + if (mergedListParams.size() > 0) { + mergedListParams.add(0, value); + value = mergedListParams; + } + } + } + parameters.add(value); + return new SQLVariantRefExpr("?"); } diff --git a/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java b/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java index 4da42b54d5..b60d0cf74d 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java @@ -15,6 +15,7 @@ */ package com.alibaba.druid.sql.visitor; +import java.util.ArrayList; import java.util.List; import com.alibaba.druid.sql.ast.SQLDataType; @@ -23,10 +24,8 @@ import com.alibaba.druid.sql.ast.SQLObject; import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator; -import com.alibaba.druid.sql.ast.expr.SQLCharExpr; import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr; import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr; -import com.alibaba.druid.sql.ast.expr.SQLNullExpr; import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition; import com.alibaba.druid.sql.ast.statement.SQLSelectOrderByItem; @@ -154,6 +153,16 @@ public class ParameterizedOutputVisitorUtils { return false; } + public final static String ATTR_MERGED = "parameterized.mergedList"; + static void putMergedArribute(SQLObject object, SQLObject item) { + List mergedList = (List) object.getAttribute(ATTR_MERGED); + if (mergedList == null) { + mergedList = new ArrayList(); + object.putAttribute(ATTR_MERGED, mergedList); + } + mergedList.add(item); + } + public static SQLBinaryOpExpr merge(ParameterizedVisitor v, SQLBinaryOpExpr x) { SQLExpr left = x.getLeft(); SQLExpr right = x.getRight(); @@ -201,10 +210,11 @@ public class ParameterizedOutputVisitorUtils { if (x.getLeft() instanceof SQLBinaryOpExpr) { SQLExpr mergedLeft = merge(v, (SQLBinaryOpExpr) x.getLeft()); if (mergedLeft != x.getLeft()) { - x = new SQLBinaryOpExpr(mergedLeft, x.getOperator(), x.getRight()); + SQLBinaryOpExpr tmp = new SQLBinaryOpExpr(mergedLeft, x.getOperator(), x.getRight()); + tmp.setParent(parent); + x = tmp; v.incrementReplaceCunt(); } - x.setParent(parent); } // ID = ? OR ID = ? => ID = ? @@ -215,6 +225,8 @@ public class ParameterizedOutputVisitorUtils { if (mergeEqual(leftBinary, rightBinary)) { v.incrementReplaceCunt(); + leftBinary.setParent(x.getParent()); + putMergedArribute(leftBinary, rightBinary); return leftBinary; } @@ -222,6 +234,7 @@ public class ParameterizedOutputVisitorUtils { && leftBinary.getOperator() == SQLBinaryOperator.BooleanOr) { if (mergeEqual(leftBinary.getRight(), x.getRight())) { v.incrementReplaceCunt(); + putMergedArribute(leftBinary, rightBinary); return leftBinary; } } 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 c9fd08787a..cee9010cef 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -318,6 +318,25 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet x = ParameterizedOutputVisitorUtils.merge(this, x); } + if (parameters != null + && parameters.size() > 0 + && x.getOperator() == SQLBinaryOperator.Equality + && x.getRight() instanceof SQLVariantRefExpr + ) { + SQLVariantRefExpr right = (SQLVariantRefExpr) x.getRight(); + int index = right.getIndex(); + if (index >= 0 && index < parameters.size()) { + Object param = parameters.get(index); + if (param instanceof Collection) { + x.getLeft().accept(this); + print0(" IN ("); + right.accept(this); + print(')'); + return false; + } + } + } + SQLObject parent = x.getParent(); boolean isRoot = parent instanceof SQLSelectQueryBlock; boolean relational = x.getOperator() == SQLBinaryOperator.BooleanAnd @@ -571,11 +590,34 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet } } if (isNumber) { - int start = quote ? 1 : 0; - String realName = name.substring(start, pos); - print0(realName); - incrementReplaceCunt(); - return false; + boolean isAlias = false; + for (SQLObject parent = x.getParent();parent != null; parent = parent.getParent()) { + if (parent instanceof SQLSelectQueryBlock) { + SQLTableSource from = ((SQLSelectQueryBlock) parent).getFrom(); + if (quote) { + String name2 = name.substring(1, name.length() - 1); + if (isTableSourceAlias(from, name, name2)) { + isAlias = true; + } + } else { + if (isTableSourceAlias(from, name)) { + isAlias = true; + } + } + break; + } + } + + if (!isAlias) { + int start = quote ? 1 : 0; + String realName = name.substring(start, pos); + print0(realName); + incrementReplaceCunt(); + return false; + } else { + print0(name); + return false; + } } } @@ -866,7 +908,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet for (SQLObject parent = x.getParent();parent != null; parent = parent.getParent()) { if (parent instanceof SQLSelectQueryBlock) { SQLTableSource from = ((SQLSelectQueryBlock) parent).getFrom(); - if (containsAlias(from, mapTableName, ownerName)) { + if (isTableSourceAlias(from, mapTableName, ownerName)) { mapTableName = null; } break; @@ -887,8 +929,9 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet return false; } - protected boolean containsAlias(SQLTableSource from, String... tableNames) { + protected boolean isTableSourceAlias(SQLTableSource from, String... tableNames) { String alias = from.getAlias(); + if (alias != null) { for (String tableName : tableNames) { if (alias.equalsIgnoreCase(tableName)) { @@ -907,8 +950,8 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet } if (from instanceof SQLJoinTableSource) { SQLJoinTableSource join = (SQLJoinTableSource) from; - return containsAlias(join.getLeft(), tableNames) - || containsAlias(join.getRight(), tableNames); + return isTableSourceAlias(join.getLeft(), tableNames) + || isTableSourceAlias(join.getRight(), tableNames); } return false; } @@ -1235,7 +1278,23 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet Object param = parameters.get(index); - if (param instanceof Collection && x.getParent() instanceof SQLInListExpr) { + SQLObject parent = x.getParent(); + + boolean in; + if (parent instanceof SQLInListExpr) { + in = true; + } else if (parent instanceof SQLBinaryOpExpr) { + SQLBinaryOpExpr binaryOpExpr = (SQLBinaryOpExpr) parent; + if (binaryOpExpr.getOperator() == SQLBinaryOperator.Equality) { + in = true; + } else { + in = false; + } + } else { + in = false; + } + + if (in && param instanceof Collection) { boolean first = true; for (Object item : (Collection) param) { if (!first) { @@ -2053,6 +2112,31 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet if (x.isOrReplace()) { print0(ucase ? "OR REPLACE " : "or replace "); } + + incrementIndent(); + String algorithm = x.getAlgorithm(); + if (algorithm != null && algorithm.length() > 0) { + print0(ucase ? "ALGORITHM = " : "algorithm = "); + print0(algorithm); + println(); + } + + SQLName definer = x.getDefiner(); + if (definer != null) { + print0(ucase ? "DEFINER = " : "definer = "); + definer.accept(this); + println(); + } + + String sqlSecurity = x.getSqlSecurity(); + if (sqlSecurity != null && sqlSecurity.length() > 0) { + print0(ucase ? "SQL SECURITY = " : "sql security = "); + print0(sqlSecurity); + println(); + } + + decrementIndent(); + print0(ucase ? "VIEW " : "view "); if (x.isIfNotExists()) { 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 0e9910e87d..b9db7ab5bb 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SchemaStatVisitor.java @@ -54,6 +54,7 @@ import com.alibaba.druid.sql.ast.expr.SQLSequenceExpr; import com.alibaba.druid.sql.ast.statement.*; import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlExpr; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitorAdapter; +import com.alibaba.druid.sql.dialect.odps.ast.OdpsValuesTableSource; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleExpr; import com.alibaba.druid.sql.dialect.postgresql.visitor.PGASTVisitorAdapter; import com.alibaba.druid.stat.TableStat; @@ -62,6 +63,7 @@ import com.alibaba.druid.stat.TableStat.Condition; import com.alibaba.druid.stat.TableStat.Mode; import com.alibaba.druid.stat.TableStat.Relationship; import com.alibaba.druid.util.JdbcConstants; +import com.alibaba.druid.util.StringUtils; public class SchemaStatVisitor extends SQLASTVisitorAdapter { @@ -518,6 +520,10 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { } for (SQLExpr item : valueExprs) { + Column valueColumn = getColumn(item); + if (valueColumn != null) { + continue; + } Object value = SQLEvalVisitorUtils.eval(getDbType(), item, parameters, false); condition.getValues().add(value); } @@ -541,6 +547,10 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { } } + if (expr instanceof SQLCastExpr) { + expr = ((SQLCastExpr) expr).getExpr(); + } + if (expr instanceof SQLPropertyExpr) { SQLExpr owner = ((SQLPropertyExpr) expr).getOwner(); String column = ((SQLPropertyExpr) expr).getName(); @@ -850,10 +860,17 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { List selectList = null; if (query instanceof SQLSelectQueryBlock) { queryBlock = (SQLSelectQueryBlock) query; + + if (queryBlock.getGroupBy() != null) { + return null; + } + selectList = queryBlock.getSelectList(); } if (selectList != null) { + boolean allColumn = false; + String allColumnOwner = null; for (SQLSelectItem item : selectList) { if (!item.getClass().equals(SQLSelectItem.class)) { continue; @@ -885,7 +902,52 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { } } } + + if (itemExpr instanceof SQLAllColumnExpr) { + allColumn = true; + } else if (itemExpr instanceof SQLPropertyExpr) { + SQLPropertyExpr propertyExpr = (SQLPropertyExpr) itemExpr; + if (propertyExpr.getName().equals("*")) { + SQLExpr owner = propertyExpr.getOwner(); + if (owner instanceof SQLIdentifierExpr) { + allColumnOwner = ((SQLIdentifierExpr) owner).getName(); + allColumn = true; + } + } + } } + + if (allColumn) { + + SQLTableSource from = queryBlock.getFrom(); + String tableName = getTable(from, allColumnOwner); + if (tableName != null) { + return new Column(tableName, alias); + } + } + } + + return null; + } + + private String getTable(SQLTableSource from, String tableAlias) { + if (from instanceof SQLExprTableSource) { + boolean aliasEq = StringUtils.equals(from.getAlias(), tableAlias); + SQLExpr tableSourceExpr = ((SQLExprTableSource) from).getExpr(); + if (tableSourceExpr instanceof SQLName) { + String tableName = ((SQLName) tableSourceExpr).toString(); + if (tableAlias == null || aliasEq) { + return tableName; + } + } + } else if (from instanceof SQLJoinTableSource) { + SQLJoinTableSource joinTableSource = (SQLJoinTableSource) from; + String leftMatchTableName = getTable(joinTableSource.getLeft(), tableAlias); + if (leftMatchTableName != null) { + return leftMatchTableName; + } + + return getTable(joinTableSource.getRight(), tableAlias); } return null; @@ -904,7 +966,7 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { return false; } - Column column; + Column column = null; if (currentTable != null) { column = addColumn(currentTable, ident); @@ -913,7 +975,22 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter { } x.putAttribute(ATTR_COLUMN, column); } else { - column = handleUnkownColumn(ident); + boolean skip = false; + for (SQLObject parent = x.getParent();parent != null;parent = parent.getParent()) { + if (parent instanceof SQLSelectQueryBlock) { + SQLTableSource from = ((SQLSelectQueryBlock) parent).getFrom(); + + if (from instanceof OdpsValuesTableSource) { + skip = true; + break; + } + } else if (parent instanceof SQLSelectQuery) { + break; + } + } + if (!skip) { + column = handleUnkownColumn(ident); + } if (column != null) { x.putAttribute(ATTR_COLUMN, column); } diff --git a/src/main/java/com/alibaba/druid/util/JdbcConstants.java b/src/main/java/com/alibaba/druid/util/JdbcConstants.java index 04ef40ce8a..9922db8976 100644 --- a/src/main/java/com/alibaba/druid/util/JdbcConstants.java +++ b/src/main/java/com/alibaba/druid/util/JdbcConstants.java @@ -39,6 +39,7 @@ public interface JdbcConstants { public static final String ORACLE = "oracle"; public static final String ORACLE_DRIVER = "oracle.jdbc.OracleDriver"; + public static final String ORACLE_DRIVER2 = "oracle.jdbc.driver.OracleDriver"; public static final String ALI_ORACLE = "AliOracle"; public static final String ALI_ORACLE_DRIVER = "com.alibaba.jdbc.AlibabaDriver"; diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/alter/MySqlAlterTableAlterColumnTest.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/alter/MySqlAlterTableAlterColumnTest.java new file mode 100644 index 0000000000..d5fea0965a --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/alter/MySqlAlterTableAlterColumnTest.java @@ -0,0 +1,40 @@ +/* + * Copyright 1999-2101 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.mysql.alter; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; +import com.alibaba.druid.sql.parser.Token; +import junit.framework.TestCase; +import org.junit.Assert; + +public class MySqlAlterTableAlterColumnTest extends TestCase { + + public void test_alter_first() throws Exception { + String sql = "ALTER TABLE `cube_template` ADD `stat_report_json` VARCHAR(256) CHARSET utf8 COLLATE utf8_general_ci DEFAULT '' NOT NULL COMMENT '模板的统计报表json数组';"; + MySqlStatementParser parser = new MySqlStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + parser.match(Token.EOF); + + Assert.assertEquals("ALTER TABLE `cube_template`\n" + + "\tADD COLUMN `stat_report_json` VARCHAR(256) CHARSET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '模板的统计报表json数组'", SQLUtils.toMySqlString(stmt)); + + Assert.assertEquals("alter table `cube_template`\n" + + "\tadd column `stat_report_json` VARCHAR(256) charset utf8 COLLATE utf8_general_ci not null default '' comment '模板的统计报表json数组'", SQLUtils.toMySqlString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/create/MySqlCreateViewTest1.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/create/MySqlCreateViewTest1.java new file mode 100644 index 0000000000..928b7d3071 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/create/MySqlCreateViewTest1.java @@ -0,0 +1,110 @@ +/* + * Copyright 1999-2101 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.mysql.create; + +import com.alibaba.druid.sql.MysqlTest; +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.ast.statement.SQLCreateViewStatement; +import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; +import com.alibaba.druid.stat.TableStat.Column; +import org.junit.Assert; + +import java.util.List; + +public class MySqlCreateViewTest1 extends MysqlTest { + + public void test_0() throws Exception { + String sql = "CREATE ALGORITHM=UNDEFINED DEFINER=root@localhost SQL SECURITY DEFINER VIEW view_audit_enroll AS " + + "SELECT a.enroll_id AS 'enrollId', case when ((SELECT audit FROM actvty_audit WHERE enroll_id = a.enroll_id AND rankjurisdiction = 1) > 0) then \"县站已审核\" else NULL end AS 'countyAudit', case when ((SELECT audit FROM actvty_audit WHERE enroll_id = a.enroll_id AND rankjurisdiction = 2) > 0) then \"市馆已审核\" else NULL end AS 'cityAudit', case when ((SELECT audit FROM actvty_audit WHERE enroll_id = a.enroll_id AND rankjurisdiction = 3) > 0) then \"省馆已审核\" else NULL end AS 'provinceAudit' FROM actvty_audit a GROUP BY a.enroll_id"; + + MySqlStatementParser parser = new MySqlStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLCreateViewStatement stmt = (SQLCreateViewStatement) statementList.get(0); +// print(statementList); + + Assert.assertEquals(1, statementList.size()); + + MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor(); + stmt.accept(visitor); + + Assert.assertEquals("CREATE ALGORITHM = UNDEFINED\n" + + "\tDEFINER = root\n" + + "\tSQL SECURITY = DEFINER\n" + + "\tVIEW view_audit_enroll\n" + + "AS\n" + + "SELECT a.enroll_id AS 'enrollId', CASE WHEN (\n" + + "\t\tSELECT audit\n" + + "\t\tFROM actvty_audit\n" + + "\t\tWHERE enroll_id = a.enroll_id\n" + + "\t\t\tAND rankjurisdiction = 1\n" + + "\t\t) > 0 THEN '县站已审核' ELSE NULL END AS 'countyAudit', CASE WHEN (\n" + + "\t\tSELECT audit\n" + + "\t\tFROM actvty_audit\n" + + "\t\tWHERE enroll_id = a.enroll_id\n" + + "\t\t\tAND rankjurisdiction = 2\n" + + "\t\t) > 0 THEN '市馆已审核' ELSE NULL END AS 'cityAudit', CASE WHEN (\n" + + "\t\tSELECT audit\n" + + "\t\tFROM actvty_audit\n" + + "\t\tWHERE enroll_id = a.enroll_id\n" + + "\t\t\tAND rankjurisdiction = 3\n" + + "\t\t) > 0 THEN '省馆已审核' ELSE NULL END AS 'provinceAudit'\n" + + "FROM actvty_audit a\n" + + "GROUP BY a.enroll_id", // + SQLUtils.toMySqlString(stmt)); + + Assert.assertEquals("create algorithm = UNDEFINED\n" + + "\tdefiner = root\n" + + "\tsql security = DEFINER\n" + + "\tview view_audit_enroll\n" + + "as\n" + + "select a.enroll_id as 'enrollId', case when (\n" + + "\t\tselect audit\n" + + "\t\tfrom actvty_audit\n" + + "\t\twhere enroll_id = a.enroll_id\n" + + "\t\t\tand rankjurisdiction = 1\n" + + "\t\t) > 0 then '县站已审核' else null end as 'countyAudit', case when (\n" + + "\t\tselect audit\n" + + "\t\tfrom actvty_audit\n" + + "\t\twhere enroll_id = a.enroll_id\n" + + "\t\t\tand rankjurisdiction = 2\n" + + "\t\t) > 0 then '市馆已审核' else null end as 'cityAudit', case when (\n" + + "\t\tselect audit\n" + + "\t\tfrom actvty_audit\n" + + "\t\twhere enroll_id = a.enroll_id\n" + + "\t\t\tand rankjurisdiction = 3\n" + + "\t\t) > 0 then '省馆已审核' else null end as 'provinceAudit'\n" + + "from actvty_audit a\n" + + "group by a.enroll_id", // + SQLUtils.toMySqlString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); + +// System.out.println("Tables : " + visitor.getTables()); +// System.out.println("fields : " + visitor.getColumns()); +// System.out.println("coditions : " + visitor.getConditions()); +// System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(1, visitor.getTables().size()); + Assert.assertEquals(3, visitor.getColumns().size()); + Assert.assertEquals(2, visitor.getConditions().size()); + + Assert.assertTrue(visitor.getTables().containsKey(new TableStat.Name("actvty_audit"))); + + Assert.assertTrue(visitor.getColumns().contains(new Column("actvty_audit", "audit"))); + Assert.assertTrue(visitor.getColumns().contains(new Column("actvty_audit", "enroll_id"))); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_30.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_30.java new file mode 100644 index 0000000000..4195b6a677 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_30.java @@ -0,0 +1,98 @@ +package com.alibaba.druid.bvt.sql.mysql.param; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils; +import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by wenshao on 16/8/23. + */ +public class MySqlParameterizedOutputVisitorTest_30 extends TestCase { + public void test_for_parameterize() throws Exception { + final String dbType = JdbcConstants.MYSQL; + + + String sql = "/* 0a67bca314863468702364451e/0.3// */select `udata`.`id` as `id`,`udata`.`gmt_create` as `gmtCreate`,`udata`.`gmt_modified` as `gmtModified`,`udata`.`uid` as `userId`,`udata`.`user_nick` as `userNick`,`udata`.`user_type` as `userType`,`udata`.`aps` as `acPeSe`,`udata`.`rn` as `rn`,`udata`.`start_period_time` as `startPeriodTime`,`udata`.`ept` as `adTm`,`udata`.`status` as `status`,`udata`.`charging_period` as `chargingPeriod`,`udata`.`sn` as `sn`,`udata`.`cpd` as `chargingPeriodDesc`,`udata`.`task_total_num` as `taskTotalNum`,`udata`.`tcn` as `taCoNu`,`udata`.`task_type` as `taskType`,`udata`.`ilbu` as `isLaBiUs`" + + " from `udata_0888` `udata` where ((`udata`.`id` IN (" + + " (select MAX(`udata`.`id`) " + + " from `udata_0888` `udata` " + + " where ((`udata`.`uid` = 1039100792) AND (`udata`.`user_type` = 2) AND (`udata`.`start_period_time` <= '2017-01-01 00:00:00') AND (`udata`.`status` = 10) AND (`udata`.`charging_period` = 1) AND (`udata`.`task_type` = 1) AND (`udata`.`task_total_num` <= `udata`.`tcn`)) group by `udata`.`charging_period`,`udata`.`start_period_time`,`udata`.`ept`))) AND ((`udata`.`uid` = '1039100792') AND (`udata`.`user_type` = 2))) order by `udata`.`start_period_time` desc limit 0,6"; + + String psql = ParameterizedOutputVisitorUtils.parameterize(sql, dbType); + assertEquals("SELECT `udata`.`id` AS `id`, `udata`.`gmt_create` AS `gmtCreate`, `udata`.`gmt_modified` AS `gmtModified`, `udata`.`uid` AS `userId`, `udata`.`user_nick` AS `userNick`\n" + + "\t, `udata`.`user_type` AS `userType`, `udata`.`aps` AS `acPeSe`, `udata`.`rn` AS `rn`, `udata`.`start_period_time` AS `startPeriodTime`, `udata`.`ept` AS `adTm`\n" + + "\t, `udata`.`status` AS `status`, `udata`.`charging_period` AS `chargingPeriod`, `udata`.`sn` AS `sn`, `udata`.`cpd` AS `chargingPeriodDesc`, `udata`.`task_total_num` AS `taskTotalNum`\n" + + "\t, `udata`.`tcn` AS `taCoNu`, `udata`.`task_type` AS `taskType`, `udata`.`ilbu` AS `isLaBiUs`\n" + + "FROM udata `udata`\n" + + "WHERE `udata`.`id` IN (SELECT MAX(`udata`.`id`)\n" + + "\t\tFROM udata `udata`\n" + + "\t\tWHERE `udata`.`uid` = ?\n" + + "\t\t\tAND `udata`.`user_type` = ?\n" + + "\t\t\tAND `udata`.`start_period_time` <= ?\n" + + "\t\t\tAND `udata`.`status` = ?\n" + + "\t\t\tAND `udata`.`charging_period` = ?\n" + + "\t\t\tAND `udata`.`task_type` = ?\n" + + "\t\t\tAND `udata`.`task_total_num` <= `udata`.`tcn`\n" + + "\t\tGROUP BY `udata`.`charging_period`, `udata`.`start_period_time`, `udata`.`ept`)\n" + + "\tAND (`udata`.`uid` = ?\n" + + "\t\tAND `udata`.`user_type` = ?)\n" + + "ORDER BY `udata`.`start_period_time` DESC\n" + + "LIMIT ?, ?", psql); + + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); + List stmtList = parser.parseStatementList(); + + StringBuilder out = new StringBuilder(); + SQLASTOutputVisitor visitor = SQLUtils.createOutputVisitor(out, JdbcConstants.MYSQL); + List parameters = new ArrayList(); + visitor.setParameterized(true); + visitor.setParameterizedMergeInList(true); + visitor.setParameters(parameters); + visitor.setExportTables(true); + /*visitor.setPrettyFormat(false);*/ + + SQLStatement stmt = stmtList.get(0); + stmt.accept(visitor); + + // System.out.println(parameters); + assertEquals(10, parameters.size()); + + //SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(psql, dbType); + // List stmtList = parser.parseStatementList(); + SQLStatement pstmt = SQLUtils.parseStatements(psql, dbType).get(0); + + StringBuilder buf = new StringBuilder(); + SQLASTOutputVisitor visitor1 = SQLUtils.createOutputVisitor(buf, dbType); + visitor1.addTableMapping("udata", "udata_0888"); + visitor1.setParameters(visitor.getParameters()); + pstmt.accept(visitor1); + + assertEquals("SELECT `udata`.`id` AS `id`, `udata`.`gmt_create` AS `gmtCreate`, `udata`.`gmt_modified` AS `gmtModified`, `udata`.`uid` AS `userId`, `udata`.`user_nick` AS `userNick`\n" + + "\t, `udata`.`user_type` AS `userType`, `udata`.`aps` AS `acPeSe`, `udata`.`rn` AS `rn`, `udata`.`start_period_time` AS `startPeriodTime`, `udata`.`ept` AS `adTm`\n" + + "\t, `udata`.`status` AS `status`, `udata`.`charging_period` AS `chargingPeriod`, `udata`.`sn` AS `sn`, `udata`.`cpd` AS `chargingPeriodDesc`, `udata`.`task_total_num` AS `taskTotalNum`\n" + + "\t, `udata`.`tcn` AS `taCoNu`, `udata`.`task_type` AS `taskType`, `udata`.`ilbu` AS `isLaBiUs`\n" + + "FROM udata_0888 `udata`\n" + + "WHERE `udata`.`id` IN (SELECT MAX(`udata`.`id`)\n" + + "\t\tFROM udata_0888 `udata`\n" + + "\t\tWHERE `udata`.`uid` = 1039100792\n" + + "\t\t\tAND `udata`.`user_type` = 2\n" + + "\t\t\tAND `udata`.`start_period_time` <= '2017-01-01 00:00:00'\n" + + "\t\t\tAND `udata`.`status` = 10\n" + + "\t\t\tAND `udata`.`charging_period` = 1\n" + + "\t\t\tAND `udata`.`task_type` = 1\n" + + "\t\t\tAND `udata`.`task_total_num` <= `udata`.`tcn`\n" + + "\t\tGROUP BY `udata`.`charging_period`, `udata`.`start_period_time`, `udata`.`ept`)\n" + + "\tAND (`udata`.`uid` = '1039100792'\n" + + "\t\tAND `udata`.`user_type` = 2)\n" + + "ORDER BY `udata`.`start_period_time` DESC\n" + + "LIMIT 0, 6", buf.toString()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_31.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_31.java new file mode 100644 index 0000000000..b023bd1046 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_31.java @@ -0,0 +1,95 @@ +package com.alibaba.druid.bvt.sql.mysql.param; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils; +import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by wenshao on 16/8/23. + */ +public class MySqlParameterizedOutputVisitorTest_31 extends TestCase { + public void test_for_parameterize() throws Exception { + final String dbType = JdbcConstants.MYSQL; + + + String sql = "/* 0a67bca314863468702364451e/0.3// */select `udata`.`id` as `id`,`udata`.`gmt_create` as `gmtCreate`,`udata`.`gmt_modified` as `gmtModified`,`udata`.`uid` as `userId`,`udata`.`user_nick` as `userNick`,`udata`.`user_type` as `userType`,`udata`.`aps` as `acPeSe`,`udata`.`rn` as `rn`,`udata`.`start_period_time` as `startPeriodTime`,`udata`.`ept` as `adTm`,`udata`.`status` as `status`,`udata`.`charging_period` as `chargingPeriod`,`udata`.`sn` as `sn`,`udata`.`cpd` as `chargingPeriodDesc`,`udata`.`task_total_num` as `taskTotalNum`,`udata`.`tcn` as `taCoNu`,`udata`.`task_type` as `taskType`,`udata`.`ilbu` as `isLaBiUs`" + + " from `udata_0888` `udata` where ((`udata`.`id` IN ((select MAX(`udata`.`id`) from `udata_0888` `udata` where ((`udata`.`uid` = 1039100792) AND (`udata`.`user_type` = 2) AND (`udata`.`start_period_time` <= '2017-01-01 00:00:00') AND (`udata`.`status` = 10) AND (`udata`.`charging_period` = 1) AND (`udata`.`task_type` = 1) AND (`udata`.`task_total_num` <= `udata`.`tcn`)) group by `udata`.`charging_period`,`udata`.`start_period_time`,`udata`.`ept`))) AND ((`udata`.`uid` = '1039100792') AND (`udata`.`user_type` = 2))) order by `udata`.`start_period_time` desc limit 0,6"; + + String psql = ParameterizedOutputVisitorUtils.parameterize(sql, dbType); + assertEquals("SELECT `udata`.`id` AS `id`, `udata`.`gmt_create` AS `gmtCreate`, `udata`.`gmt_modified` AS `gmtModified`, `udata`.`uid` AS `userId`, `udata`.`user_nick` AS `userNick`\n" + + "\t, `udata`.`user_type` AS `userType`, `udata`.`aps` AS `acPeSe`, `udata`.`rn` AS `rn`, `udata`.`start_period_time` AS `startPeriodTime`, `udata`.`ept` AS `adTm`\n" + + "\t, `udata`.`status` AS `status`, `udata`.`charging_period` AS `chargingPeriod`, `udata`.`sn` AS `sn`, `udata`.`cpd` AS `chargingPeriodDesc`, `udata`.`task_total_num` AS `taskTotalNum`\n" + + "\t, `udata`.`tcn` AS `taCoNu`, `udata`.`task_type` AS `taskType`, `udata`.`ilbu` AS `isLaBiUs`\n" + + "FROM udata `udata`\n" + + "WHERE `udata`.`id` IN (SELECT MAX(`udata`.`id`)\n" + + "\t\tFROM udata `udata`\n" + + "\t\tWHERE `udata`.`uid` = ?\n" + + "\t\t\tAND `udata`.`user_type` = ?\n" + + "\t\t\tAND `udata`.`start_period_time` <= ?\n" + + "\t\t\tAND `udata`.`status` = ?\n" + + "\t\t\tAND `udata`.`charging_period` = ?\n" + + "\t\t\tAND `udata`.`task_type` = ?\n" + + "\t\t\tAND `udata`.`task_total_num` <= `udata`.`tcn`\n" + + "\t\tGROUP BY `udata`.`charging_period`, `udata`.`start_period_time`, `udata`.`ept`)\n" + + "\tAND (`udata`.`uid` = ?\n" + + "\t\tAND `udata`.`user_type` = ?)\n" + + "ORDER BY `udata`.`start_period_time` DESC\n" + + "LIMIT ?, ?", psql); + + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); + List stmtList = parser.parseStatementList(); + + StringBuilder out = new StringBuilder(); + SQLASTOutputVisitor visitor = SQLUtils.createOutputVisitor(out, JdbcConstants.MYSQL); + List parameters = new ArrayList(); + visitor.setParameterized(true); + visitor.setParameterizedMergeInList(true); + visitor.setParameters(parameters); + visitor.setExportTables(true); + /*visitor.setPrettyFormat(false);*/ + + SQLStatement stmt = stmtList.get(0); + stmt.accept(visitor); + + // System.out.println(parameters); + assertEquals(10, parameters.size()); + + //SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(psql, dbType); + // List stmtList = parser.parseStatementList(); + SQLStatement pstmt = SQLUtils.parseStatements(psql, dbType).get(0); + + StringBuilder buf = new StringBuilder(); + SQLASTOutputVisitor visitor1 = SQLUtils.createOutputVisitor(buf, dbType); + visitor1.addTableMapping("udata", "udata_0888"); + visitor1.setParameters(visitor.getParameters()); + pstmt.accept(visitor1); + + assertEquals("SELECT `udata`.`id` AS `id`, `udata`.`gmt_create` AS `gmtCreate`, `udata`.`gmt_modified` AS `gmtModified`, `udata`.`uid` AS `userId`, `udata`.`user_nick` AS `userNick`\n" + + "\t, `udata`.`user_type` AS `userType`, `udata`.`aps` AS `acPeSe`, `udata`.`rn` AS `rn`, `udata`.`start_period_time` AS `startPeriodTime`, `udata`.`ept` AS `adTm`\n" + + "\t, `udata`.`status` AS `status`, `udata`.`charging_period` AS `chargingPeriod`, `udata`.`sn` AS `sn`, `udata`.`cpd` AS `chargingPeriodDesc`, `udata`.`task_total_num` AS `taskTotalNum`\n" + + "\t, `udata`.`tcn` AS `taCoNu`, `udata`.`task_type` AS `taskType`, `udata`.`ilbu` AS `isLaBiUs`\n" + + "FROM udata_0888 `udata`\n" + + "WHERE `udata`.`id` IN (SELECT MAX(`udata`.`id`)\n" + + "\t\tFROM udata_0888 `udata`\n" + + "\t\tWHERE `udata`.`uid` = 1039100792\n" + + "\t\t\tAND `udata`.`user_type` = 2\n" + + "\t\t\tAND `udata`.`start_period_time` <= '2017-01-01 00:00:00'\n" + + "\t\t\tAND `udata`.`status` = 10\n" + + "\t\t\tAND `udata`.`charging_period` = 1\n" + + "\t\t\tAND `udata`.`task_type` = 1\n" + + "\t\t\tAND `udata`.`task_total_num` <= `udata`.`tcn`\n" + + "\t\tGROUP BY `udata`.`charging_period`, `udata`.`start_period_time`, `udata`.`ept`)\n" + + "\tAND (`udata`.`uid` = '1039100792'\n" + + "\t\tAND `udata`.`user_type` = 2)\n" + + "ORDER BY `udata`.`start_period_time` DESC\n" + + "LIMIT 0, 6", buf.toString()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_32.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_32.java new file mode 100644 index 0000000000..27d801b9e2 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_32.java @@ -0,0 +1,85 @@ +package com.alibaba.druid.bvt.sql.mysql.param; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils; +import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by wenshao on 16/8/23. + */ +public class MySqlParameterizedOutputVisitorTest_32 extends TestCase { + public void test_for_parameterize() throws Exception { + final String dbType = JdbcConstants.MYSQL; + + + String sql = "/* cds internal mark */select count(*) as count from (" + + "( select env_type from `tmall_miaoscm`.`miao_sale_ledger_0060` where `id` > 1 limit 136 )" + + " union all ( select env_type from `tmall_miaoscm`.`miao_sale_ledger_0060` where `id` > 2331 limit 136 )" + + ") as miao_sale_ledger_0060 where `miao_sale_ledger_0060`.`env_type` = 3"; + + String psql = ParameterizedOutputVisitorUtils.parameterize(sql, dbType); + assertEquals("SELECT COUNT(*) AS count\n" + + "FROM (\n" + + "\t(SELECT env_type\n" + + "\tFROM `tmall_miaoscm`.miao_sale_ledger\n" + + "\tWHERE `id` > ?\n" + + "\tLIMIT ?)\n" + + "\tUNION ALL\n" + + "\t(SELECT env_type\n" + + "\tFROM `tmall_miaoscm`.miao_sale_ledger\n" + + "\tWHERE `id` > ?\n" + + "\tLIMIT ?)\n" + + ") miao_sale_ledger_0060\n" + + "WHERE `miao_sale_ledger_0060`.`env_type` = ?", psql); + + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); + List stmtList = parser.parseStatementList(); + + StringBuilder out = new StringBuilder(); + SQLASTOutputVisitor visitor = SQLUtils.createOutputVisitor(out, JdbcConstants.MYSQL); + List parameters = new ArrayList(); + visitor.setParameterized(true); + visitor.setParameterizedMergeInList(true); + visitor.setParameters(parameters); + visitor.setExportTables(true); + /*visitor.setPrettyFormat(false);*/ + + SQLStatement stmt = stmtList.get(0); + stmt.accept(visitor); + + // System.out.println(parameters); + assertEquals(5, parameters.size()); + + //SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(psql, dbType); + // List stmtList = parser.parseStatementList(); + SQLStatement pstmt = SQLUtils.parseStatements(psql, dbType).get(0); + + StringBuilder buf = new StringBuilder(); + SQLASTOutputVisitor visitor1 = SQLUtils.createOutputVisitor(buf, dbType); + visitor1.addTableMapping("udata", "udata_0888"); + visitor1.setParameters(visitor.getParameters()); + pstmt.accept(visitor1); + + assertEquals("SELECT COUNT(*) AS count\n" + + "FROM (\n" + + "\t(SELECT env_type\n" + + "\tFROM `tmall_miaoscm`.miao_sale_ledger\n" + + "\tWHERE `id` > 1\n" + + "\tLIMIT 136)\n" + + "\tUNION ALL\n" + + "\t(SELECT env_type\n" + + "\tFROM `tmall_miaoscm`.miao_sale_ledger\n" + + "\tWHERE `id` > 2331\n" + + "\tLIMIT 136)\n" + + ") miao_sale_ledger_0060\n" + + "WHERE `miao_sale_ledger_0060`.`env_type` = 3", buf.toString()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_33.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_33.java new file mode 100644 index 0000000000..daa1736276 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_33.java @@ -0,0 +1,62 @@ +package com.alibaba.druid.bvt.sql.mysql.param; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils; +import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by wenshao on 16/8/23. + */ +public class MySqlParameterizedOutputVisitorTest_33 extends TestCase { + public void test_for_parameterize() throws Exception { + final String dbType = JdbcConstants.MYSQL; + + + String sql = "select * from t where id = 1 or id = 2"; + + String psql = ParameterizedOutputVisitorUtils.parameterize(sql, dbType); + assertEquals("SELECT *\n" + + "FROM t\n" + + "WHERE id = ?", psql); + + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); + List stmtList = parser.parseStatementList(); + + StringBuilder out = new StringBuilder(); + SQLASTOutputVisitor visitor = SQLUtils.createOutputVisitor(out, JdbcConstants.MYSQL); + List parameters = new ArrayList(); + visitor.setParameterized(true); + visitor.setParameterizedMergeInList(true); + visitor.setParameters(parameters); + visitor.setExportTables(true); + /*visitor.setPrettyFormat(false);*/ + + SQLStatement stmt = stmtList.get(0); + stmt.accept(visitor); + + // System.out.println(parameters); + assertEquals(1, parameters.size()); + + //SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(psql, dbType); + // List stmtList = parser.parseStatementList(); + SQLStatement pstmt = SQLUtils.parseStatements(psql, dbType).get(0); + + StringBuilder buf = new StringBuilder(); + SQLASTOutputVisitor visitor1 = SQLUtils.createOutputVisitor(buf, dbType); + visitor1.addTableMapping("udata", "udata_0888"); + visitor1.setParameters(visitor.getParameters()); + pstmt.accept(visitor1); + + assertEquals("SELECT *\n" + + "FROM t\n" + + "WHERE id IN (1, 2)", buf.toString()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_34.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_34.java new file mode 100644 index 0000000000..d28553c714 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_34.java @@ -0,0 +1,62 @@ +package com.alibaba.druid.bvt.sql.mysql.param; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils; +import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by wenshao on 16/8/23. + */ +public class MySqlParameterizedOutputVisitorTest_34 extends TestCase { + public void test_for_parameterize() throws Exception { + final String dbType = JdbcConstants.MYSQL; + + + String sql = "select * from t where id = 1 or id = 2 or id = 3"; + + String psql = ParameterizedOutputVisitorUtils.parameterize(sql, dbType); + assertEquals("SELECT *\n" + + "FROM t\n" + + "WHERE id = ?", psql); + + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); + List stmtList = parser.parseStatementList(); + + StringBuilder out = new StringBuilder(); + SQLASTOutputVisitor visitor = SQLUtils.createOutputVisitor(out, JdbcConstants.MYSQL); + List parameters = new ArrayList(); + visitor.setParameterized(true); + visitor.setParameterizedMergeInList(true); + visitor.setParameters(parameters); + visitor.setExportTables(true); + /*visitor.setPrettyFormat(false);*/ + + SQLStatement stmt = stmtList.get(0); + stmt.accept(visitor); + + // System.out.println(parameters); + assertEquals(1, parameters.size()); + + //SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(psql, dbType); + // List stmtList = parser.parseStatementList(); + SQLStatement pstmt = SQLUtils.parseStatements(psql, dbType).get(0); + + StringBuilder buf = new StringBuilder(); + SQLASTOutputVisitor visitor1 = SQLUtils.createOutputVisitor(buf, dbType); + visitor1.addTableMapping("udata", "udata_0888"); + visitor1.setParameters(visitor.getParameters()); + pstmt.accept(visitor1); + + assertEquals("SELECT *\n" + + "FROM t\n" + + "WHERE id IN (1, 2, 3)", buf.toString()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsMultiInsertTest2.java b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsMultiInsertTest2.java new file mode 100644 index 0000000000..132ce7fce3 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsMultiInsertTest2.java @@ -0,0 +1,24 @@ +package com.alibaba.druid.bvt.sql.odps; + +import com.alibaba.druid.sql.SQLUtils; +import junit.framework.TestCase; +import org.junit.Assert; + +public class OdpsMultiInsertTest2 extends TestCase { + public void test_for_multi_insert() throws Exception { + String sql = "from sale_detail\n" + + "insert overwrite table sale_detail_multi partition (sale_date='2010', region='china' )\n" + + "select shop_name, customer_id, total_price\n" + + "insert overwrite table sale_detail_multi partition (sale_date='2011', region='china' )\n" + + "select shop_name, customer_id, total_price;\n"; + Assert.assertEquals("FROM sale_detail\n" + + "INSERT OVERWRITE TABLE sale_detail_multi PARTITION (sale_date='2010', region='china')\n" + + "SELECT shop_name\n" + + "\t, customer_id\n" + + "\t, total_price\n" + + "INSERT OVERWRITE TABLE sale_detail_multi PARTITION (sale_date='2011', region='china')\n" + + "SELECT shop_name\n" + + "\t, customer_id\n" + + "\t, total_price;", SQLUtils.formatOdps(sql)); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest21.java b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest21.java new file mode 100644 index 0000000000..122015d593 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/odps/OdpsSelectTest21.java @@ -0,0 +1,58 @@ +/* + * Copyright 1999-2101 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.odps; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.util.List; + +public class OdpsSelectTest21 extends TestCase { + + public void test_select() throws Exception { + // 1095288847322 + String sql = "select wm_concat(',', a) from values('abc', 1), (null, 2) t (a, i);";// + Assert.assertEquals("SELECT WM_CONCAT(',', a)\n" + + "FROM VALUES ('abc', 1), (NULL, 2) t (a, i);", SQLUtils.formatOdps(sql)); + Assert.assertEquals("select wm_concat(',', a)\n" + + "from values ('abc', 1), (null, 2) t (a, i);", SQLUtils.formatOdps(sql, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION)); + + List statementList = SQLUtils.parseStatements(sql, JdbcConstants.ODPS); + SQLStatement stmt = statementList.get(0); + + Assert.assertEquals(1, statementList.size()); + + SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.ODPS); + stmt.accept(visitor); + +// System.out.println("Tables : " + visitor.getTables()); + System.out.println("fields : " + visitor.getColumns()); +// System.out.println("coditions : " + visitor.getConditions()); +// System.out.println("orderBy : " + visitor.getOrderByColumns()); + + Assert.assertEquals(0, visitor.getTables().size()); + Assert.assertEquals(0, visitor.getColumns().size()); + Assert.assertEquals(0, visitor.getConditions().size()); + +// Assert.assertTrue(visitor.getColumns().contains(new Column("abc", "name"))); + } + + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/schemaStat/SchemaStatTest10.java b/src/test/java/com/alibaba/druid/bvt/sql/schemaStat/SchemaStatTest10.java new file mode 100644 index 0000000000..4f27a967b3 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/schemaStat/SchemaStatTest10.java @@ -0,0 +1,41 @@ +package com.alibaba.druid.bvt.sql.schemaStat; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.util.Set; + +public class SchemaStatTest10 extends TestCase { + + public void test_schemaStat() throws Exception { + String sql = "select a.id, b.name from table1 a inner join table2 b on a.id = b.id"; + + String dbType = JdbcConstants.ORACLE; + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); + SQLStatement stmt = parser.parseStatementList().get(0); + + SchemaStatVisitor statVisitor = SQLUtils.createSchemaStatVisitor(dbType); + stmt.accept(statVisitor); + + Set relationships = statVisitor.getRelationships(); + for (TableStat.Relationship relationship : relationships) { + System.out.println(relationship); // table1.id = table2.id + } + +// System.out.println(statVisitor.getColumns()); +// System.out.println(statVisitor.getGroupByColumns()); // group by + System.out.println("relationships : " + statVisitor.getRelationships()); // group by +// System.out.println(statVisitor.getConditions()); + + Assert.assertEquals(3, statVisitor.getColumns().size()); + Assert.assertEquals(2, statVisitor.getConditions().size()); + assertEquals(0, statVisitor.getFunctions().size()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/schemaStat/SchemaStatTest11.java b/src/test/java/com/alibaba/druid/bvt/sql/schemaStat/SchemaStatTest11.java new file mode 100644 index 0000000000..08fe643fe5 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/schemaStat/SchemaStatTest11.java @@ -0,0 +1,42 @@ +package com.alibaba.druid.bvt.sql.schemaStat; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.util.Set; + +public class SchemaStatTest11 extends TestCase { + + public void test_schemaStat() throws Exception { + String sql = "select a.id, b.name from (select * from table1) a inner join table2 b on a.id = b.id"; + + String dbType = JdbcConstants.ORACLE; + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); + SQLStatement stmt = parser.parseStatementList().get(0); + + SchemaStatVisitor statVisitor = SQLUtils.createSchemaStatVisitor(dbType); + stmt.accept(statVisitor); + + Set relationships = statVisitor.getRelationships(); + for (TableStat.Relationship relationship : relationships) { + System.out.println(relationship); // table1.id = table2.id + } + +// System.out.println(statVisitor.getColumns()); +// System.out.println(statVisitor.getGroupByColumns()); // group by + System.out.println("relationships : " + statVisitor.getRelationships()); // group by + System.out.println(statVisitor.getConditions()); + assertEquals(1, relationships.size()); + + Assert.assertEquals(3, statVisitor.getColumns().size()); + Assert.assertEquals(2, statVisitor.getConditions().size()); + assertEquals(0, statVisitor.getFunctions().size()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/schemaStat/SchemaStatTest12.java b/src/test/java/com/alibaba/druid/bvt/sql/schemaStat/SchemaStatTest12.java new file mode 100644 index 0000000000..9cdcde9e92 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/schemaStat/SchemaStatTest12.java @@ -0,0 +1,57 @@ +package com.alibaba.druid.bvt.sql.schemaStat; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.util.Set; + +public class SchemaStatTest12 extends TestCase { + + public void test_schemaStat() throws Exception { + String sql = "select work_no , nick_name , name , ifnull(sum(investment_percentage ) / 100 , 0 ) as invest_percent " + + "from ( " + + " select t1.id , t1.work_no , t2.nick_name , t2.name , t2.super_work_no , t2.super_nick_name , t2.super_name " + + " , t3.project_name , t1.investment_percentage , t4.dept_name " + + " from t_pm_aur t2 " + + " left outer join ( " + + " select * from t_pm_rs_acl " + + " where is_deleted = 0 and prj_biz_id is not null and ivt_pt > 0 and iwk = '2016W17' " + + " ) t1 on t2.work_no = t1.work_no " + + " left outer join ( " + + " select * from t_pm_prj_i " + + " where( status not in( 'DEPRECATED' , 'FINISHED' ) or status is null ) and( task_type not in( 'WEEKLY_REPORT' ) or task_type is null ) and is_deleted = 0 " + + " ) t3 on t1.prj_biz_id = t3.biz_id " + + " left outer join t_pm_dpt t4 on t2.dept_no = t4.biz_id " + + " where t4.dept_name like 'MY-XDSYB-JSB%' and t2.emp_type in( 'R' , 'V' ) and t2.is_deleted = 'N' and t2.work_status = 'A' " + + ") t5 group by work_no , nick_name , name having invest_percent < 1.0 "; + + String dbType = JdbcConstants.ORACLE; + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); + SQLStatement stmt = parser.parseStatementList().get(0); + + SchemaStatVisitor statVisitor = SQLUtils.createSchemaStatVisitor(dbType); + stmt.accept(statVisitor); + + Set relationships = statVisitor.getRelationships(); + for (TableStat.Relationship relationship : relationships) { + System.out.println(relationship); // table1.id = table2.id + } + +// System.out.println(statVisitor.getColumns()); +// System.out.println(statVisitor.getGroupByColumns()); // group by + System.out.println("relationships : " + statVisitor.getRelationships()); // group by + System.out.println(statVisitor.getConditions()); + assertEquals(3, relationships.size()); + + Assert.assertEquals(21, statVisitor.getColumns().size()); + Assert.assertEquals(20, statVisitor.getConditions().size()); + assertEquals(1, statVisitor.getFunctions().size()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/schemaStat/SchemaStatTest13.java b/src/test/java/com/alibaba/druid/bvt/sql/schemaStat/SchemaStatTest13.java new file mode 100644 index 0000000000..e7eda98128 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/schemaStat/SchemaStatTest13.java @@ -0,0 +1,42 @@ +package com.alibaba.druid.bvt.sql.schemaStat; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.util.Set; + +public class SchemaStatTest13 extends TestCase { + + public void test_schemaStat() throws Exception { + String sql = "select a.id, b.name from (select t1.* from table1 t1 left join table3 t3 on cast(t1.id as bigint) = t3.id) a inner join table2 b on a.id = b.id"; + + String dbType = JdbcConstants.ORACLE; + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); + SQLStatement stmt = parser.parseStatementList().get(0); + + SchemaStatVisitor statVisitor = SQLUtils.createSchemaStatVisitor(dbType); + stmt.accept(statVisitor); + + Set relationships = statVisitor.getRelationships(); + for (TableStat.Relationship relationship : relationships) { + System.out.println(relationship); // table1.id = table2.id + } + +// System.out.println(statVisitor.getColumns()); +// System.out.println(statVisitor.getGroupByColumns()); // group by + System.out.println("relationships : " + statVisitor.getRelationships()); // group by + System.out.println(statVisitor.getConditions()); + assertEquals(2, relationships.size()); + + Assert.assertEquals(5, statVisitor.getColumns().size()); + Assert.assertEquals(3, statVisitor.getConditions().size()); + assertEquals(0, statVisitor.getFunctions().size()); + } +} diff --git a/src/test/java/com/alibaba/druid/demo/sql/SchemaStatTest_odps.java b/src/test/java/com/alibaba/druid/demo/sql/SchemaStatTest_odps.java new file mode 100644 index 0000000000..3604adf7f9 --- /dev/null +++ b/src/test/java/com/alibaba/druid/demo/sql/SchemaStatTest_odps.java @@ -0,0 +1,51 @@ +package com.alibaba.druid.demo.sql; + +import com.alibaba.druid.sql.SQLUtils; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.sql.visitor.SchemaStatVisitor; +import com.alibaba.druid.stat.TableStat; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.junit.Assert; + +import java.io.File; +import java.util.List; +import java.util.Set; + +public class SchemaStatTest_odps extends TestCase { + + public void test_schemaStat() throws Exception { + File file = new File("/Users/wenshao/Downloads/odps_sql_1.txt"); + String sql = FileUtils.readFileToString(file); + + String dbType = JdbcConstants.ODPS; + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); + List stmtList = parser.parseStatementList(); + + System.out.println("stmtList size : " + stmtList.size()); + + SchemaStatVisitor statVisitor = SQLUtils.createSchemaStatVisitor(dbType); + for (SQLStatement stmt : stmtList) { + stmt.accept(statVisitor); + } + + Set relationships = statVisitor.getRelationships(); + for (TableStat.Relationship relationship : relationships) { + System.out.println(relationship); // table1.id = table2.id + } + +// System.out.println(statVisitor.getColumns()); +// System.out.println(statVisitor.getGroupByColumns()); // group by + System.out.println("relationships : " + statVisitor.getRelationships()); // group by + System.out.println(statVisitor.getConditions()); +// assertEquals(3, relationships.size()); +// +// Assert.assertEquals(21, statVisitor.getColumns().size()); +// Assert.assertEquals(20, statVisitor.getConditions().size()); +// assertEquals(1, statVisitor.getFunctions().size()); + } +}