improved sql parser. add new feature JdbcUtils.getCreateTableScript, for issue #1342

This commit is contained in:
wenshao
2017-07-24 01:16:43 +08:00
parent 2d8ded4f0c
commit 7a241d7da5
28 changed files with 662 additions and 40 deletions
@@ -42,9 +42,7 @@ import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.util.StringUtils;
import com.alibaba.druid.util.Utils;
import com.alibaba.druid.util.*;
public class SQLUtils {
public static FormatOption DEFAULT_FORMAT_OPTION = new FormatOption(true, true);
@@ -774,6 +772,10 @@ public class SQLUtils {
}
public static String normalize(String name) {
return normalize(name, null);
}
public static String normalize(String name, String dbType) {
if (name == null) {
return null;
}
@@ -782,7 +784,19 @@ public class SQLUtils {
char c0 = name.charAt(0);
char x0 = name.charAt(name.length() - 1);
if ((c0 == '"' && x0 == '"') || (c0 == '`' && x0 == '`')) {
name = name.substring(1, name.length() - 1);
String normalizeName = name.substring(1, name.length() - 1);
if (JdbcConstants.ORACLE.equals(dbType)) {
if (OracleUtils.isKeyword(normalizeName)) {
return name;
}
} else if (JdbcConstants.MYSQL.equals(dbType)) {
if (MySqlUtils.isKeyword(normalizeName)) {
return name;
}
}
return normalizeName;
}
}
@@ -20,7 +20,7 @@ import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public abstract class SQLStatementImpl extends SQLObjectImpl implements SQLStatement {
private String dbType;
protected String dbType;
private boolean afterSemi;
@@ -26,8 +26,10 @@ import com.alibaba.druid.sql.ast.SQLObjectImpl;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.util.JdbcConstants;
public class SQLColumnDefinition extends SQLObjectImpl implements SQLTableElement {
protected String dbType;
protected SQLName name;
protected SQLDataType dataType;
@@ -287,6 +289,7 @@ public class SQLColumnDefinition extends SQLObjectImpl implements SQLTableElemen
public SQLColumnDefinition clone() {
SQLColumnDefinition x = new SQLColumnDefinition();
x.setDbType(dbType);
if(name != null) {
x.setName(name.clone());
@@ -341,4 +344,26 @@ public class SQLColumnDefinition extends SQLObjectImpl implements SQLTableElemen
return x;
}
public String getDbType() {
return dbType;
}
public void setDbType(String dbType) {
this.dbType = dbType;
}
public void simplify() {
enable = null;
validate = null;
rely = null;
if (this.name instanceof SQLIdentifierExpr) {
SQLIdentifierExpr identExpr = (SQLIdentifierExpr) this.name;
String columnName = identExpr.getName();
columnName = SQLUtils.normalize(columnName, dbType);
identExpr.setName(columnName);
}
}
}
@@ -23,4 +23,6 @@ public interface SQLConstraint extends SQLObject {
SQLName getName();
void setName(SQLName value);
void simplify();
}
@@ -15,13 +15,16 @@
*/
package com.alibaba.druid.sql.ast.statement;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLCommentHint;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLObjectImpl;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import java.util.List;
public abstract class SQLConstraintImpl extends SQLObjectImpl implements SQLConstraint {
protected String dbType;
protected SQLName name;
private Boolean enable;
@@ -90,4 +93,21 @@ public abstract class SQLConstraintImpl extends SQLObjectImpl implements SQLCons
public void setRely(Boolean rely) {
this.rely = rely;
}
public String getDbType() {
return dbType;
}
public void setDbType(String dbType) {
this.dbType = dbType;
}
public void simplify() {
if (this.name instanceof SQLIdentifierExpr) {
SQLIdentifierExpr identExpr = (SQLIdentifierExpr) this.name;
String columnName = identExpr.getName();
columnName = SQLUtils.normalize(columnName, dbType);
identExpr.setName(columnName);
}
}
}
@@ -20,11 +20,13 @@ import java.util.*;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.*;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlTableIndex;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.util.ListDG;
import com.alibaba.druid.util.lang.Consumer;
import org.apache.ibatis.jdbc.SQL;
public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLStatement {
@@ -59,6 +61,10 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS
this.setTableSource(new SQLExprTableSource(name));
}
public void setName(String name) {
this.setName(new SQLIdentifierExpr(name));
}
public SQLExprTableSource getTableSource() {
return tableSource;
}
@@ -414,4 +420,37 @@ public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLS
}
}
public void simplify() {
SQLName name = getName();
if (name instanceof SQLPropertyExpr) {
String tableName = ((SQLPropertyExpr) name).getName();
tableName = SQLUtils.normalize(tableName);
setName(tableName);
name = getName();
}
if (name instanceof SQLIdentifierExpr) {
SQLIdentifierExpr identExpr = (SQLIdentifierExpr) name;
String tableName = identExpr.getName();
tableName = SQLUtils.normalize(tableName, dbType);
identExpr.setName(tableName);
}
if (name instanceof SQLIdentifierExpr) {
SQLIdentifierExpr identExpr = (SQLIdentifierExpr) name;
String tableName = identExpr.getName();
tableName = SQLUtils.normalize(tableName);
identExpr.setName(tableName);
}
for (SQLTableElement element : this.tableElementList) {
if (element instanceof SQLColumnDefinition) {
SQLColumnDefinition column = (SQLColumnDefinition) element;
column.simplify();
} else if (element instanceof SQLConstraint) {
((SQLConstraint) element).simplify();
}
}
}
}
@@ -18,8 +18,10 @@ package com.alibaba.druid.sql.ast.statement;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
public class SQLUnique extends SQLConstraintImpl implements SQLUniqueConstraint, SQLTableElement {
@@ -58,4 +60,17 @@ public class SQLUnique extends SQLConstraintImpl implements SQLUniqueConstraint,
x.addColumn(columnClone);
}
}
public void simplify() {
super.simplify();
for (SQLExpr column : columns) {
if (column instanceof SQLIdentifierExpr) {
SQLIdentifierExpr identExpr = (SQLIdentifierExpr) column;
String columnName = identExpr.getName();
columnName = SQLUtils.normalize(columnName, dbType);
identExpr.setName(columnName);
}
}
}
}
@@ -21,17 +21,17 @@ import com.alibaba.druid.sql.ast.statement.SQLUnique;
import com.alibaba.druid.sql.ast.statement.SQLUniqueConstraint;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.util.JdbcConstants;
public class MySqlKey extends SQLUnique implements SQLUniqueConstraint, SQLTableConstraint {
private SQLName indexName;
private String indexType;
private boolean hasConstaint;
public MySqlKey(){
dbType = JdbcConstants.MYSQL;
}
@Override
@@ -45,7 +45,7 @@ public class MySqlKey extends SQLUnique implements SQLUniqueConstraint, SQLTable
if (visitor.visit(this)) {
acceptChild(visitor, this.getName());
acceptChild(visitor, this.getColumns());
acceptChild(visitor, indexName);
acceptChild(visitor, name);
}
visitor.endVisit(this);
}
@@ -58,14 +58,6 @@ public class MySqlKey extends SQLUnique implements SQLUniqueConstraint, SQLTable
this.indexType = indexType;
}
public SQLName getIndexName() {
return indexName;
}
public void setIndexName(SQLName indexName) {
this.indexName = indexName;
}
public boolean isHasConstaint() {
return hasConstaint;
}
@@ -17,11 +17,12 @@ package com.alibaba.druid.sql.dialect.mysql.ast;
import com.alibaba.druid.sql.ast.statement.SQLPrimaryKey;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
import com.alibaba.druid.util.JdbcConstants;
public class MySqlPrimaryKey extends MySqlKey implements SQLPrimaryKey {
public MySqlPrimaryKey(){
dbType = JdbcConstants.MYSQL;
}
protected void accept0(MySqlASTVisitor visitor) {
@@ -28,7 +28,6 @@ public class MySqlUnique extends MySqlKey implements SQLPrimaryKey {
if (visitor.visit(this)) {
acceptChild(visitor, this.getName());
acceptChild(visitor, this.getColumns());
acceptChild(visitor, this.getIndexName());
}
visitor.endVisit(this);
}
@@ -19,6 +19,7 @@ import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.statement.SQLForeignKeyImpl;
import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import com.alibaba.druid.util.JdbcConstants;
/**
* @author kiki
@@ -34,6 +35,10 @@ public class MysqlForeignKey extends SQLForeignKeyImpl {
protected Option onUpdate;
protected Option onDelete;
public MysqlForeignKey() {
dbType = JdbcConstants.MYSQL;
}
public SQLName getIndexName() {
return indexName;
}
@@ -165,8 +165,13 @@ public class MySqlCreateTableStatement extends SQLCreateTableStatement implement
return tableGroup;
}
public void setTableGroup(SQLName tableGroup) {
this.tableGroup = tableGroup;
}
@Override
public void simplify() {
tableOptions.clear();
super.simplify();
}
}
@@ -774,7 +774,7 @@ public class MySqlCreateTableParser extends SQLCreateTableParser {
if (lexer.token() == Token.IDENTIFIER || lexer.token() == Token.LITERAL_ALIAS) {
SQLName indexName = this.exprParser.name();
if (indexName != null) {
key.setIndexName(indexName);
key.setName(indexName);
}
}
@@ -542,6 +542,7 @@ public class MySqlExprParser extends SQLExprParser {
public SQLColumnDefinition parseColumn() {
SQLColumnDefinition column = new SQLColumnDefinition();
column.setDbType(dbType);
column.setName(name());
column.setDataType(parseDataType());
@@ -813,7 +814,7 @@ public class MySqlExprParser extends SQLExprParser {
if (lexer.token() != Token.LPAREN) {
SQLName indexName = name();
unique.setIndexName(indexName);
unique.setName(indexName);
}
//5.5语法 USING BTREE 放在index 名字后
@@ -585,9 +585,10 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
print0(ucase ? "KEY" : "key");
if (x.getIndexName() != null) {
SQLName name = x.getName();
if (name != null) {
print(' ');
x.getIndexName().accept(this);
name.accept(this);
}
if (x.getIndexType() != null) {
@@ -2844,9 +2845,10 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
print0(ucase ? "UNIQUE" : "unique");
if (x.getIndexName() != null) {
SQLName name = x.getName();
if (name != null) {
print(' ');
x.getIndexName().accept(this);
name.accept(this);
}
if (x.getIndexType() != null) {
@@ -78,6 +78,29 @@ public class OracleCreateTableStatement extends SQLCreateTableStatement implemen
private SQLName of;
private OIDIndex oidIndex;
private boolean monitoring;
public void simplify() {
tablespace = null;
storage = null;
lobStorage = null;
pctfree = null;
pctused = null;
initrans = null;
maxtrans = null;
pctincrease = null;
logging = null;
compress = null;
compressLevel = null;
compressForOltp = false;
onCommitPreserveRows = false;
onCommitDeleteRows = false;
super.simplify();
}
public OracleCreateTableStatement() {
super (JdbcConstants.ORACLE);
@@ -466,4 +489,5 @@ public class OracleCreateTableStatement extends SQLCreateTableStatement implemen
this.name = name;
}
}
}
@@ -192,6 +192,7 @@ public class SQLServerExprParser extends SQLExprParser {
public SQLColumnDefinition createColumnDefinition() {
SQLColumnDefinition column = new SQLColumnDefinition();
column.setDbType(dbType);
return column;
}
@@ -1980,6 +1980,7 @@ public class SQLExprParser extends SQLParser {
public SQLColumnDefinition createColumnDefinition() {
SQLColumnDefinition column = new SQLColumnDefinition();
column.setDbType(dbType);
return column;
}
@@ -1012,13 +1012,14 @@ public class SQLStatementParser extends SQLParser {
lexer.nextToken();
SQLExpr comment = this.exprParser.primary();
SQLColumnDefinition columnDefinition = new SQLColumnDefinition();
columnDefinition.setName(columnName);
columnDefinition.setComment(comment);
SQLColumnDefinition column = new SQLColumnDefinition();
column.setDbType(dbType);
column.setName(columnName);
column.setComment(comment);
SQLAlterTableAlterColumn changeColumn = new SQLAlterTableAlterColumn();
changeColumn.setColumn(columnDefinition);
changeColumn.setColumn(column);
stmt.addItem(changeColumn);
} else {
@@ -2232,6 +2233,7 @@ public class SQLStatementParser extends SQLParser {
createView.addColumn(constraint);
} else {
SQLColumnDefinition column = new SQLColumnDefinition();
column.setDbType(dbType);
SQLName expr = this.exprParser.name();
column.setName(expr);
@@ -1311,8 +1311,11 @@ public class SchemaStatVisitor extends SQLASTVisitorAdapter {
if (aliasMap != null) {
String alias = x.getAlias();
if (alias != null && !aliasMap.containsKey(alias)) {
putAliasMap(aliasMap, alias, ident);
if (alias != null) {
String table = aliasMap.get(alias);
if (!(ident.equals(table) || alias.equals(table))) {
putAliasMap(aliasMap, alias, ident);
}
}
if (!aliasMap.containsKey(ident)) {
putAliasMap(aliasMap, ident, ident);
@@ -766,4 +766,20 @@ public final class JdbcUtils implements JdbcConstants {
close(conn);
}
}
public static String getCreateTableScript(String dbType, Connection conn) throws SQLException {
return getCreateTableScript(dbType, conn, true, true);
}
public static String getCreateTableScript(String dbType, Connection conn, boolean sorted, boolean simplify) throws SQLException {
if (JdbcConstants.MYSQL.equals(dbType)) {
return MySqlUtils.getCreateTableScript(conn, sorted, simplify);
}
if (JdbcConstants.ORACLE.equals(dbType)) {
return OracleUtils.getCreateTableScript(conn, sorted, simplify);
}
throw new SQLException("getCreateTableScript dbType not support for " + dbType);
}
}
@@ -15,7 +15,9 @@
*/
package com.alibaba.druid.util;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.mysql.jdbc.ConnectionImpl;
import com.mysql.jdbc.MySQLConnection;
import com.mysql.jdbc.MysqlIO;
@@ -25,11 +27,10 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class MySqlUtils {
@@ -126,4 +127,91 @@ public class MySqlUtils {
return words.contains(name_lower);
}
public static List<String> showTables(Connection conn) throws SQLException {
List<String> tables = new ArrayList<String>();
Statement stmt = null;
ResultSet rs = null;
try {
stmt = conn.createStatement();
rs = stmt.executeQuery("show tables");
while (rs.next()) {
String tableName = rs.getString(1);
tables.add(tableName);
}
} finally {
JdbcUtils.close(rs);
JdbcUtils.close(stmt);
}
return tables;
}
public static List<String> getTableDDL(Connection conn, List<String> tables) throws SQLException {
List<String> ddlList = new ArrayList<String>();
Statement stmt = null;
try {
for (String table : tables) {
if (stmt == null) {
stmt = conn.createStatement();
}
if (isKeyword(table)) {
table = "`" + table + "`";
}
ResultSet rs = null;
try {
rs = stmt.executeQuery("show create table " + table);
if (rs.next()) {
String ddl = rs.getString(2);
ddlList.add(ddl);
}
} finally {
JdbcUtils.close(rs);
}
}
} finally {
JdbcUtils.close(stmt);
}
return ddlList;
}
public static String getCreateTableScript(Connection conn) throws SQLException {
return getCreateTableScript(conn, true, true);
}
public static String getCreateTableScript(Connection conn, boolean sorted, boolean simplify) throws SQLException {
List<String> tables = showTables(conn);
List<String> ddlList = getTableDDL(conn, tables);
StringBuilder buf = new StringBuilder();
for (String ddl : ddlList) {
buf.append(ddl);
buf.append(';');
}
String ddlScript = buf.toString();
if (! (sorted || simplify)) {
return ddlScript;
}
List stmtList = SQLUtils.parseStatements(ddlScript, JdbcConstants.MYSQL);
if (simplify) {
for (Object o : stmtList) {
if (o instanceof SQLCreateTableStatement) {
SQLCreateTableStatement createTableStmt = (SQLCreateTableStatement) o;
createTableStmt.simplify();
}
}
}
if (sorted) {
SQLCreateTableStatement.sort(stmtList);
}
return SQLUtils.toSQLString(stmtList, JdbcConstants.MYSQL);
}
}
@@ -16,17 +16,17 @@
package com.alibaba.druid.util;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import java.util.*;
import javax.sql.XAConnection;
import javax.transaction.xa.XAException;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.OracleResultSet;
import oracle.jdbc.OracleStatement;
import oracle.jdbc.driver.DatabaseError;
import oracle.jdbc.internal.OraclePreparedStatement;
import oracle.jdbc.xa.client.OracleXAConnection;
import oracle.sql.ROWID;
@@ -222,4 +222,99 @@ public class OracleUtils {
return words.contains(name_lower);
}
public static List<String> showTables(Connection conn) throws SQLException {
List<String> tables = new ArrayList<String>();
Statement stmt = null;
ResultSet rs = null;
try {
stmt = conn.createStatement();
rs = stmt.executeQuery("select table_name from user_tables");
while (rs.next()) {
String tableName = rs.getString(1);
tables.add(tableName);
}
} finally {
JdbcUtils.close(rs);
JdbcUtils.close(stmt);
}
return tables;
}
public static List<String> getTableDDL(Connection conn, String... tables) throws SQLException {
return getTableDDL(conn, Arrays.asList(tables));
}
public static List<String> getTableDDL(Connection conn, List<String> tables) throws SQLException {
List<String> ddlList = new ArrayList<String>();
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
String sql = "select DBMS_METADATA.GET_DDL('TABLE', TABLE_NAME) FROM user_tables";
if (tables.size() > 0) {
sql += "IN (";
for (int i = 0; i < tables.size(); ++i) {
if (i != 0) {
sql += ", ?";
} else {
sql += "?";
}
}
sql += ")";
}
pstmt = conn.prepareStatement(sql);
for (int i = 0; i < tables.size(); ++i) {
pstmt.setString(i + 1, tables.get(i));
}
rs = pstmt.executeQuery();
while (rs.next()) {
String ddl = rs.getString(1);
ddlList.add(ddl);
}
} finally {
JdbcUtils.close(rs);
JdbcUtils.close(pstmt);
}
return ddlList;
}
public static String getCreateTableScript(Connection conn) throws SQLException {
return getCreateTableScript(conn, true, true);
}
public static String getCreateTableScript(Connection conn, boolean sorted, boolean simplify) throws SQLException {
List<String> ddlList = OracleUtils.getTableDDL(conn);
StringBuilder buf = new StringBuilder();
for (String ddl : ddlList) {
buf.append(ddl);
buf.append(';');
}
String ddlScript = buf.toString();
if (! (sorted || simplify)) {
return ddlScript;
}
List stmtList = SQLUtils.parseStatements(ddlScript, JdbcConstants.ORACLE);
if (simplify) {
for (Object o : stmtList) {
if (o instanceof SQLCreateTableStatement) {
SQLCreateTableStatement createTableStmt = (SQLCreateTableStatement) o;
createTableStmt.simplify();
}
}
}
if (sorted) {
SQLCreateTableStatement.sort(stmtList);
}
return SQLUtils.toSQLString(stmtList, JdbcConstants.ORACLE);
}
}
@@ -0,0 +1,52 @@
package com.alibaba.druid;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.util.JdbcUtils;
import junit.framework.TestCase;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
/**
* Created by wenshao on 18/05/2017.
*/
public abstract class DbTestCase extends TestCase {
protected DruidDataSource dataSource;
protected final String resource;
public DbTestCase(String resource) {
this.resource = resource;
}
protected void setUp() throws Exception {
this.dataSource = createDataSourceFromResource(resource);
}
static DruidDataSource createDataSourceFromResource(String resource) throws IOException {
Properties properties = new Properties();
InputStream configStream = null;
try {
configStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource);
properties.load(configStream);
} finally {
JdbcUtils.close(configStream);
}
DruidDataSource dataSource = new DruidDataSource();
dataSource.configFromPropety(properties);
return dataSource;
}
protected void tearDown() throws Exception {
dataSource.close();
}
public Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
}
@@ -49,7 +49,7 @@ public class MySqlDeleteTest_1 extends MysqlTest {
stmt.accept(visitor);
// System.out.println("Tables : " + visitor.getTables());
// System.out.println("fields : " + visitor.getColumns());
System.out.println("fields : " + visitor.getColumns());
// System.out.println("coditions : " + visitor.getConditions());
// System.out.println("orderBy : " + visitor.getOrderByColumns());
@@ -0,0 +1,163 @@
/*
* 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.mysql.select;
import com.alibaba.druid.sql.MysqlTest;
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 org.junit.Assert;
import java.util.List;
public class MySqlSelectTest_48_union extends MysqlTest {
public void test_0() throws Exception {
String sql = "select sum(hd.paid_amount) from\n" +
"(\n" +
"SELECT 'fl',cast(a.hosted_ymd as date) as hosted_ymd,a.user_id,'boss1',a.paid_amount,m.user_id,m.create_date,m.pmcode,n.type_name,n.product_name,n.acctype_id,n.acctype_name,n.account_name,n.plan\n" +
"FROM hive.bdc_dwd.dw_mk_copyright_order a\n" +
"left join hive.bdc_dwd.dw_mk_chance b on (a.chance_id=b.chance_id and b.acct_day='03')\n" +
"left join hive.bdc_dwd.dw_lg_stat_user m on (a.user_id =m.user_id and m.acct_day='03')\n" +
"left join hive.bdc_dwd.dw_lg_pmcode n on (m.pmcode=n.id and n.acct_day='03')\n" +
"where a.hosted_ymd between '2016-01-01' and '2017-06-30' and b.chance_type_group=3\n" +
"and a.acct_day='03'\n" +
"union\n" +
"select 'fl',b.paid_date as hosted_ymd,b.user_id,'boss2',b.paid_amount,m.user_id,m.create_date,m.pmcode,n.type_name,n.product_name,n.acctype_id,n.acctype_name,n.account_name,n.plan\n" +
"from hive.bdc_dwd.dw_fx_chance a\n" +
"left join hive.bdc_dwd.dw_fx_chance_order b on (a.chance_id=b.chance_id and b.acct_day='03')\n" +
"left join hive.bdc_dwd.dw_lg_stat_user m on (a.user_id =m.user_id and m.acct_day='03')\n" +
"left join hive.bdc_dwd.dw_lg_pmcode n on (m.pmcode=n.id and n.acct_day='03')\n" +
"where a.project_id=1 and b.paid_amount>0 and cast(b.paid_date as varchar(10))>='2016-01-01' and\n" +
"cast(b.paid_date as varchar(10))<='2017-06-30' and b.state=1 and a.acct_day='03'\n" +
")hd";
List<SQLStatement> statementList = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL, true);
SQLStatement stmt = statementList.get(0);
assertEquals(1, statementList.size());
SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(JdbcConstants.MYSQL);
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());
// assertEquals(1, visitor.getTables().size());
// assertEquals(1, visitor.getColumns().size());
// assertEquals(0, visitor.getConditions().size());
// assertEquals(0, visitor.getOrderByColumns().size());
{
String output = SQLUtils.toMySqlString(stmt);
assertEquals("SELECT SUM(hd.paid_amount)\n" +
"FROM (\n" +
"\t(SELECT 'fl', CAST(a.hosted_ymd AS date) AS hosted_ymd, a.user_id, 'boss1', a.paid_amount\n" +
"\t\t, m.user_id, m.create_date, m.pmcode, n.type_name, n.product_name\n" +
"\t\t, n.acctype_id, n.acctype_name, n.account_name, n.plan\n" +
"\tFROM hive.bdc_dwd.dw_mk_copyright_order a\n" +
"\t\tLEFT JOIN hive.bdc_dwd.dw_mk_chance b\n" +
"\t\tON a.chance_id = b.chance_id\n" +
"\t\t\tAND b.acct_day = '03'\n" +
"\t\tLEFT JOIN hive.bdc_dwd.dw_lg_stat_user m\n" +
"\t\tON a.user_id = m.user_id\n" +
"\t\t\tAND m.acct_day = '03'\n" +
"\t\tLEFT JOIN hive.bdc_dwd.dw_lg_pmcode n\n" +
"\t\tON m.pmcode = n.id\n" +
"\t\t\tAND n.acct_day = '03'\n" +
"\tWHERE a.hosted_ymd BETWEEN '2016-01-01' AND '2017-06-30'\n" +
"\t\tAND b.chance_type_group = 3\n" +
"\t\tAND a.acct_day = '03'\n" +
"\tUNION\n" +
"\tSELECT 'fl', b.paid_date AS hosted_ymd, b.user_id, 'boss2', b.paid_amount\n" +
"\t\t, m.user_id, m.create_date, m.pmcode, n.type_name, n.product_name\n" +
"\t\t, n.acctype_id, n.acctype_name, n.account_name, n.plan\n" +
"\tFROM hive.bdc_dwd.dw_fx_chance a\n" +
"\t\tLEFT JOIN hive.bdc_dwd.dw_fx_chance_order b\n" +
"\t\tON a.chance_id = b.chance_id\n" +
"\t\t\tAND b.acct_day = '03'\n" +
"\t\tLEFT JOIN hive.bdc_dwd.dw_lg_stat_user m\n" +
"\t\tON a.user_id = m.user_id\n" +
"\t\t\tAND m.acct_day = '03'\n" +
"\t\tLEFT JOIN hive.bdc_dwd.dw_lg_pmcode n\n" +
"\t\tON m.pmcode = n.id\n" +
"\t\t\tAND n.acct_day = '03'\n" +
"\tWHERE a.project_id = 1\n" +
"\t\tAND b.paid_amount > 0\n" +
"\t\tAND CAST(b.paid_date AS varchar(10)) >= '2016-01-01'\n" +
"\t\tAND CAST(b.paid_date AS varchar(10)) <= '2017-06-30'\n" +
"\t\tAND b.state = 1\n" +
"\t\tAND a.acct_day = '03')\n" +
") hd", //
output);
}
{
String output = SQLUtils.toMySqlString(stmt, SQLUtils.DEFAULT_LCASE_FORMAT_OPTION);
assertEquals("select sum(hd.paid_amount)\n" +
"from (\n" +
"\t(select 'fl', cast(a.hosted_ymd as date) as hosted_ymd, a.user_id, 'boss1', a.paid_amount\n" +
"\t\t, m.user_id, m.create_date, m.pmcode, n.type_name, n.product_name\n" +
"\t\t, n.acctype_id, n.acctype_name, n.account_name, n.plan\n" +
"\tfrom hive.bdc_dwd.dw_mk_copyright_order a\n" +
"\t\tleft join hive.bdc_dwd.dw_mk_chance b\n" +
"\t\ton a.chance_id = b.chance_id\n" +
"\t\t\tand b.acct_day = '03'\n" +
"\t\tleft join hive.bdc_dwd.dw_lg_stat_user m\n" +
"\t\ton a.user_id = m.user_id\n" +
"\t\t\tand m.acct_day = '03'\n" +
"\t\tleft join hive.bdc_dwd.dw_lg_pmcode n\n" +
"\t\ton m.pmcode = n.id\n" +
"\t\t\tand n.acct_day = '03'\n" +
"\twhere a.hosted_ymd between '2016-01-01' and '2017-06-30'\n" +
"\t\tand b.chance_type_group = 3\n" +
"\t\tand a.acct_day = '03'\n" +
"\tunion\n" +
"\tselect 'fl', b.paid_date as hosted_ymd, b.user_id, 'boss2', b.paid_amount\n" +
"\t\t, m.user_id, m.create_date, m.pmcode, n.type_name, n.product_name\n" +
"\t\t, n.acctype_id, n.acctype_name, n.account_name, n.plan\n" +
"\tfrom hive.bdc_dwd.dw_fx_chance a\n" +
"\t\tleft join hive.bdc_dwd.dw_fx_chance_order b\n" +
"\t\ton a.chance_id = b.chance_id\n" +
"\t\t\tand b.acct_day = '03'\n" +
"\t\tleft join hive.bdc_dwd.dw_lg_stat_user m\n" +
"\t\ton a.user_id = m.user_id\n" +
"\t\t\tand m.acct_day = '03'\n" +
"\t\tleft join hive.bdc_dwd.dw_lg_pmcode n\n" +
"\t\ton m.pmcode = n.id\n" +
"\t\t\tand n.acct_day = '03'\n" +
"\twhere a.project_id = 1\n" +
"\t\tand b.paid_amount > 0\n" +
"\t\tand cast(b.paid_date as varchar(10)) >= '2016-01-01'\n" +
"\t\tand cast(b.paid_date as varchar(10)) <= '2017-06-30'\n" +
"\t\tand b.state = 1\n" +
"\t\tand a.acct_day = '03')\n" +
") hd", //
output);
}
{
String output = SQLUtils.toMySqlString(stmt, new SQLUtils.FormatOption(true, true, true));
assertEquals("SELECT student_name, GROUP_CONCAT(DISTINCT test_score ORDER BY test_score DESC SEPARATOR ' ')\n" +
"FROM student\n" +
"GROUP BY student_name;", //
output);
}
}
}
@@ -0,0 +1,29 @@
package com.alibaba.druid.mysql;
import com.alibaba.druid.DbTestCase;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.util.JdbcUtils;
import com.alibaba.druid.util.MySqlUtils;
import com.alibaba.druid.util.OracleUtils;
import java.sql.Connection;
import java.util.List;
/**
* Created by wenshao on 23/07/2017.
*/
public class MySql_getCreateTableScriptTest extends DbTestCase {
public MySql_getCreateTableScriptTest() {
super("pool_config/mysql_db.properties");
}
public void test_oracle() throws Exception {
Connection conn = getConnection();
String createTableScript = JdbcUtils.getCreateTableScript(JdbcConstants.MYSQL, conn);
System.out.println(createTableScript);
conn.close();
}
}
@@ -0,0 +1,28 @@
package com.alibaba.druid.oracle;
import com.alibaba.druid.DbTestCase;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.druid.util.JdbcUtils;
import com.alibaba.druid.util.OracleUtils;
import java.sql.Connection;
import java.util.List;
/**
* Created by wenshao on 23/07/2017.
*/
public class Oracle_getCreateTableScriptTest extends DbTestCase {
public Oracle_getCreateTableScriptTest() {
super("pool_config/oracle_db.properties");
}
public void test_oracle() throws Exception {
Connection conn = getConnection();
// 从Oracle通过DBMS_METADATA.GET_DDL获取CreateTable语句列表
String createTableScript = JdbcUtils.getCreateTableScript(JdbcConstants.ORACLE, conn);
conn.close();
}
}