mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
refactor sql parser & support tableMapping. issue #1432
This commit is contained in:
@@ -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(' ');
|
||||
|
||||
+2
@@ -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;
|
||||
|
||||
+4
-20
@@ -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) {
|
||||
|
||||
+2
-17
@@ -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();
|
||||
|
||||
+3
-20
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user