refactor sql parser & support tableMapping. issue #1432

This commit is contained in:
wenshao
2016-09-25 05:06:50 +08:00
parent 2e478b1869
commit a26e4c546d
33 changed files with 430 additions and 177 deletions
@@ -17,6 +17,7 @@ package com.alibaba.druid.sql;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.alibaba.druid.DruidRuntimeException;
import com.alibaba.druid.sql.ast.SQLExpr;
@@ -263,10 +264,18 @@ public class SQLUtils {
}
public static String toSQLString(List<SQLStatement> statementList, String dbType, List<Object> parameters) {
return toSQLString(statementList, dbType, parameters, null);
return toSQLString(statementList, dbType, parameters, null, null);
}
public static String toSQLString(List<SQLStatement> statementList, String dbType, List<Object> parameters, FormatOption option) {
return toSQLString(statementList, dbType, parameters, option, null);
}
public static String toSQLString(List<SQLStatement> statementList
, String dbType
, List<Object> parameters
, FormatOption option
, Map<String, String> tableMapping) {
StringBuilder out = new StringBuilder();
SQLASTOutputVisitor visitor = createFormatOutputVisitor(out, statementList, dbType);
if (parameters != null) {
@@ -278,6 +287,10 @@ public class SQLUtils {
}
visitor.setUppCase(option.isUppCase());
if (tableMapping != null) {
visitor.setTableMapping(tableMapping);
}
for (int i = 0; i < statementList.size(); i++) {
SQLStatement stmt = statementList.get(i);
@@ -645,5 +658,10 @@ public class SQLUtils {
this.ucase = val;
}
}
public static String refactor(String dbType, String sql, Map<String, String> tableMapping) {
List<SQLStatement> stmtList = parseStatements(sql, dbType);
return SQLUtils.toSQLString(stmtList, dbType, null, null, tableMapping);
}
}
@@ -467,7 +467,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
print0(ucase ? "IF NOT EXISTS " : "if not exists ");
}
x.getName().accept(this);
printTableSourceExpr(x.getName());
if (x.getLike() != null) {
print0(ucase ? " LIKE " : " like ");
@@ -2659,7 +2659,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
}
public boolean visit(SQLExprTableSource x) {
x.getExpr().accept(this);
printTableSourceExpr(x.getExpr());
if (x.getAlias() != null) {
print(' ');
@@ -15,6 +15,8 @@
*/
package com.alibaba.druid.sql.dialect.mysql.visitor;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.SQLObject;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
@@ -619,7 +619,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
public boolean visit(OracleSelectTableReference x) {
if (x.isOnly()) {
print0(ucase ? "ONLY (" : "only (");
x.getExpr().accept(this);
printTableSourceExpr(x.getExpr());
if (x.getPartition() != null) {
print(' ');
@@ -628,7 +628,7 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
print(')');
} else {
x.getExpr().accept(this);
printTableSourceExpr(x.getExpr());
if (x.getPartition() != null) {
print(' ');
@@ -1285,27 +1285,11 @@ public class OracleOutputVisitor extends SQLASTOutputVisitor implements OracleAS
x.getTableSource().accept(this);
if (x.getColumns().size() > 0) {
incrementIndent();
println();
print('(');
for (int i = 0, size = x.getColumns().size(); i < size; ++i) {
if (i != 0) {
if (i % 5 == 0) {
println();
}
print0(", ");
}
x.getColumns().get(i).accept(this);
}
print(')');
decrementIndent();
}
printInsertColumns(x.getColumns());
if (x.getValues() != null) {
println();
print0(ucase ? "VALUES" : "values");
println();
print0(ucase ? "VALUES " : "values ");
x.getValues().accept(this);
} else {
if (x.getQuery() != null) {
@@ -291,7 +291,7 @@ public class PGOutputVisitor extends SQLASTOutputVisitor implements PGASTVisitor
print0(ucase ? "ONLY " : "only ");
}
x.getTableName().accept(this);
printTableSourceExpr(x.getTableName());
if (x.getAlias() != null) {
print0(ucase ? " AS " : " as ");
@@ -337,22 +337,7 @@ public class PGOutputVisitor extends SQLASTOutputVisitor implements PGASTVisitor
x.getTableSource().accept(this);
if (x.getColumns().size() > 0) {
incrementIndent();
println();
print('(');
for (int i = 0, size = x.getColumns().size(); i < size; ++i) {
if (i != 0) {
if (i % 5 == 0) {
println();
}
print0(", ");
}
x.getColumns().get(i).accept(this);
}
print(')');
decrementIndent();
}
printInsertColumns(x.getColumns());
if (x.getValues() != null) {
println();
@@ -151,23 +151,7 @@ public class SQLServerOutputVisitor extends SQLASTOutputVisitor implements SQLSe
x.getTableSource().accept(this);
if (x.getColumns().size() > 0) {
incrementIndent();
println();
print('(');
for (int i = 0, size = x.getColumns().size(); i < size; ++i) {
if (i != 0) {
if (i % 5 == 0) {
println();
}
print0(", ");
}
x.getColumns().get(i).accept(this);
}
print(')');
decrementIndent();
}
printInsertColumns(x.getColumns());
if (x.getOutput() != null) {
println();
@@ -177,8 +161,7 @@ public class SQLServerOutputVisitor extends SQLASTOutputVisitor implements SQLSe
if (x.getValuesList().size() != 0) {
println();
print0(ucase ? "VALUES" : "values");
println();
print0(ucase ? "VALUES " : "values ");
for (int i = 0, size = x.getValuesList().size(); i < size; ++i) {
if (i != 0) {
print(',');
@@ -256,7 +239,7 @@ public class SQLServerOutputVisitor extends SQLASTOutputVisitor implements SQLSe
}
public boolean visit(SQLExprTableSource x) {
x.getExpr().accept(this);
printTableSourceExpr(x.getExpr());
if (x.getAlias() != null) {
print(' ');
@@ -22,9 +22,7 @@ import java.sql.Blob;
import java.sql.Clob;
import java.sql.NClob;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.*;
import com.alibaba.druid.sql.ast.*;
import com.alibaba.druid.sql.ast.expr.*;
@@ -40,17 +38,19 @@ import com.alibaba.druid.util.JdbcConstants;
public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements PrintableVisitor {
protected final Appendable appender;
private String indent = "\t";
private int indentCount = 0;
private boolean prettyFormat = true;
protected boolean ucase = true;
protected int selectListNumberOfLine = 5;
private String indent = "\t";
private int indentCount = 0;
private boolean prettyFormat = true;
protected boolean ucase = true;
protected int selectListNumberOfLine = 5;
protected boolean groupItemSingleLine = false;
protected boolean groupItemSingleLine = false;
protected List<Object> parameters;
protected List<Object> parameters;
protected String dbType;
protected String dbType;
protected Map<String, String> tableMapping;
public SQLASTOutputVisitor(Appendable appender){
this.appender = appender;
@@ -64,6 +64,17 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab
return this.parameters.size();
}
public void addTableMapping(String srcTable, String destTable) {
if (tableMapping != null) {
tableMapping = new HashMap<String, String>();
}
tableMapping.put(srcTable, destTable);
}
public void setTableMapping(Map<String, String> tableMapping) {
this.tableMapping = tableMapping;
}
public List<Object> getParameters() {
if (parameters == null) {
parameters = new ArrayList<Object>();
@@ -772,8 +783,22 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab
return false;
}
protected void printTableSourceExpr(SQLExpr expr) {
if (tableMapping != null && expr instanceof SQLName) {
String tableName = expr.toString();
String destTableName = tableMapping.get(tableName);
if (destTableName != null) {
tableName = destTableName;
print0(tableName);
return;
}
}
expr.accept(this);
}
public boolean visit(SQLExprTableSource x) {
x.getExpr().accept(this);
printTableSourceExpr(x.getExpr());
if (x.getAlias() != null) {
print(' ');
@@ -984,10 +1009,10 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab
if (from == null) {
print0(ucase ? "DELETE FROM " : "delete from ");
x.getTableName().accept(this);
printTableSourceExpr(x.getTableName());
} else {
print0(ucase ? "DELETE " : "delete ");
x.getTableName().accept(this);
printTableSourceExpr(x.getTableName());
print0(ucase ? " FROM " : " from ");
from.accept(this);
}
@@ -1019,35 +1044,11 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab
x.getTableSource().accept(this);
if (x.getColumns().size() > 0) {
incrementIndent();
println();
print('(');
for (int i = 0, size = x.getColumns().size(); i < size; ++i) {
if (i != 0) {
if (i % 5 == 0) {
println();
}
print0(", ");
}
SQLExpr column = x.getColumns().get(i);
column.accept(this);
String dataType = (String) column.getAttribute("dataType");
if (dataType != null) {
print(' ');
print(dataType);
}
}
print(')');
decrementIndent();
}
printInsertColumns(x.getColumns());
if (!x.getValuesList().isEmpty()) {
println();
print0(ucase ? "VALUES" : "values");
println();
print0(ucase ? "VALUES " : "values ");
printAndAccept(x.getValuesList(), ", ");
} else {
if (x.getQuery() != null) {
@@ -1060,6 +1061,40 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab
return false;
}
protected void printInsertColumns(List<SQLExpr> columns) {
final int size = columns.size();
if (size > 0) {
if (size > 5) {
incrementIndent();
println();
} else {
print(' ');
}
print('(');
for (int i = 0; i < size; ++i) {
if (i != 0) {
if (i % 5 == 0) {
println();
}
print0(", ");
}
SQLExpr column = columns.get(i);
column.accept(this);
String dataType = (String) column.getAttribute("dataType");
if (dataType != null) {
print(' ');
print(dataType);
}
}
print(')');
if (size > 5) {
decrementIndent();
}
}
}
public boolean visit(SQLUpdateSetItem x) {
x.getColumn().accept(this);
print0(" = ");
@@ -1101,7 +1136,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab
print0(ucase ? "LOCAL TEMPORARY " : "local temporary ");
}
x.getName().accept(this);
printTableSourceExpr(x.getName());
int size = x.getTableElementList().size();