mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
improved sql parser performance.
This commit is contained in:
@@ -37,13 +37,15 @@ import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerSchemaStatVisito
|
||||
import com.alibaba.druid.sql.parser.*;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
|
||||
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
|
||||
import com.alibaba.druid.sql.visitor.VisitorFeature;
|
||||
import com.alibaba.druid.support.logging.Log;
|
||||
import com.alibaba.druid.support.logging.LogFactory;
|
||||
import com.alibaba.druid.util.*;
|
||||
|
||||
public class SQLUtils {
|
||||
public static FormatOption DEFAULT_FORMAT_OPTION = new FormatOption(true, true);
|
||||
public static FormatOption DEFAULT_LCASE_FORMAT_OPTION = new FormatOption(false, true);
|
||||
public static FormatOption DEFAULT_LCASE_FORMAT_OPTION
|
||||
= new FormatOption(false, true);
|
||||
|
||||
private final static Log LOG = LogFactory.getLog(SQLUtils.class);
|
||||
|
||||
@@ -61,6 +63,7 @@ public class SQLUtils {
|
||||
visitor.setUppCase(option.isUppCase());
|
||||
visitor.setPrettyFormat(option.isPrettyFormat());
|
||||
visitor.setParameterized(option.isParameterized());
|
||||
visitor.setFeatures(option.features);
|
||||
|
||||
sqlObject.accept(visitor);
|
||||
|
||||
@@ -85,7 +88,11 @@ public class SQLUtils {
|
||||
}
|
||||
|
||||
public static String toMySqlString(SQLObject sqlObject) {
|
||||
return toMySqlString(sqlObject, null);
|
||||
return toMySqlString(sqlObject, (FormatOption) null);
|
||||
}
|
||||
|
||||
public static String toMySqlString(SQLObject sqlObject, VisitorFeature... features) {
|
||||
return toMySqlString(sqlObject, new FormatOption(features));
|
||||
}
|
||||
|
||||
public static String toMySqlString(SQLObject sqlObject, FormatOption option) {
|
||||
@@ -269,10 +276,7 @@ public class SQLUtils {
|
||||
if (option == null) {
|
||||
option = DEFAULT_FORMAT_OPTION;
|
||||
}
|
||||
visitor.setUppCase(option.isUppCase());
|
||||
visitor.setPrettyFormat(option.prettyFormat);
|
||||
visitor.setParameterized(option.parameterized);
|
||||
visitor.setDesensitize(option.desensitize);
|
||||
visitor.setFeatures(option.features);
|
||||
|
||||
if (tableMapping != null) {
|
||||
visitor.setTableMapping(tableMapping);
|
||||
@@ -621,16 +625,17 @@ public class SQLUtils {
|
||||
}
|
||||
|
||||
public static class FormatOption {
|
||||
|
||||
private boolean ucase = true;
|
||||
private boolean prettyFormat = true;
|
||||
private boolean parameterized = false;
|
||||
private boolean desensitize = false;
|
||||
private int features = VisitorFeature.of(VisitorFeature.OutputUCase
|
||||
, VisitorFeature.OutputPrettyFormat);
|
||||
|
||||
public FormatOption() {
|
||||
|
||||
}
|
||||
|
||||
public FormatOption(VisitorFeature... features) {
|
||||
this.features = VisitorFeature.of(features);
|
||||
}
|
||||
|
||||
public FormatOption(boolean ucase) {
|
||||
this(ucase, true);
|
||||
}
|
||||
@@ -640,41 +645,49 @@ public class SQLUtils {
|
||||
}
|
||||
|
||||
public FormatOption(boolean ucase, boolean prettyFormat, boolean parameterized) {
|
||||
this.ucase = ucase;
|
||||
this.prettyFormat = prettyFormat;
|
||||
this.parameterized = parameterized;
|
||||
this.features = VisitorFeature.config(this.features, VisitorFeature.OutputUCase, ucase);
|
||||
this.features = VisitorFeature.config(this.features, VisitorFeature.OutputPrettyFormat, prettyFormat);
|
||||
this.features = VisitorFeature.config(this.features, VisitorFeature.OutputParameterized, parameterized);
|
||||
}
|
||||
|
||||
public boolean isDesensitize() {
|
||||
return desensitize;
|
||||
return isEnabled(VisitorFeature.OutputDesensitize);
|
||||
}
|
||||
|
||||
public void setDesensitize(boolean desensitize) {
|
||||
this.desensitize = desensitize;
|
||||
public void setDesensitize(boolean val) {
|
||||
config(VisitorFeature.OutputDesensitize, val);
|
||||
}
|
||||
|
||||
public boolean isUppCase() {
|
||||
return ucase;
|
||||
return isEnabled(VisitorFeature.OutputUCase);
|
||||
}
|
||||
|
||||
public void setUppCase(boolean val) {
|
||||
this.ucase = val;
|
||||
config(VisitorFeature.OutputUCase, val);
|
||||
}
|
||||
|
||||
public boolean isPrettyFormat() {
|
||||
return prettyFormat;
|
||||
return isEnabled(VisitorFeature.OutputPrettyFormat);
|
||||
}
|
||||
|
||||
public void setPrettyFormat(boolean prettyFormat) {
|
||||
this.prettyFormat = prettyFormat;
|
||||
config(VisitorFeature.OutputPrettyFormat, prettyFormat);
|
||||
}
|
||||
|
||||
public boolean isParameterized() {
|
||||
return parameterized;
|
||||
return isEnabled(VisitorFeature.OutputParameterized);
|
||||
}
|
||||
|
||||
public void setParameterized(boolean parameterized) {
|
||||
this.parameterized = parameterized;
|
||||
config(VisitorFeature.OutputParameterized, parameterized);
|
||||
}
|
||||
|
||||
public void config(VisitorFeature feature, boolean state) {
|
||||
features = VisitorFeature.config(features, feature, state);
|
||||
}
|
||||
|
||||
public final boolean isEnabled(VisitorFeature feature) {
|
||||
return VisitorFeature.isEnabled(this.features, feature);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -71,6 +71,8 @@ public class SQLInsertStatement extends SQLInsertInto implements SQLStatement {
|
||||
|
||||
private final List<SQLExpr> values;
|
||||
|
||||
private transient String originalString;
|
||||
|
||||
public ValuesClause(){
|
||||
this(new ArrayList<SQLExpr>());
|
||||
}
|
||||
@@ -118,6 +120,14 @@ public class SQLInsertStatement extends SQLInsertInto implements SQLStatement {
|
||||
|
||||
visitor.endVisit(this);
|
||||
}
|
||||
|
||||
public String getOriginalString() {
|
||||
return originalString;
|
||||
}
|
||||
|
||||
public void setOriginalString(String originalString) {
|
||||
this.originalString = originalString;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -44,11 +44,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlRepeatStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.clause.MySqlSelectIntoStatement;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.*;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlLockTableStatement.LockType;
|
||||
import com.alibaba.druid.sql.parser.Lexer;
|
||||
import com.alibaba.druid.sql.parser.ParserException;
|
||||
import com.alibaba.druid.sql.parser.SQLSelectParser;
|
||||
import com.alibaba.druid.sql.parser.SQLStatementParser;
|
||||
import com.alibaba.druid.sql.parser.Token;
|
||||
import com.alibaba.druid.sql.parser.*;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -2229,6 +2225,8 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
|
||||
private void parseValueClause(List<ValuesClause> valueClauseList, int columnSize) {
|
||||
for (int i = 0; ; ++i) {
|
||||
int startPos = lexer.pos() - 1;
|
||||
|
||||
if (lexer.token() != Token.LPAREN) {
|
||||
throw new ParserException("syntax error, expect ')', " + lexer.info());
|
||||
}
|
||||
@@ -2281,6 +2279,13 @@ public class MySqlStatementParser extends SQLStatementParser {
|
||||
}
|
||||
|
||||
SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause(valueExprList);
|
||||
|
||||
if (lexer.isEnabled(SQLParserFeature.KeepInsertValueClauseOriginalString)) {
|
||||
int endPos = lexer.pos();
|
||||
String orginalString = lexer.subString(startPos, endPos - startPos);
|
||||
values.setOriginalString(orginalString);
|
||||
}
|
||||
|
||||
valueClauseList.add(values);
|
||||
} else {
|
||||
SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause(new ArrayList<SQLExpr>(0));
|
||||
|
||||
@@ -47,10 +47,7 @@ import com.alibaba.druid.sql.dialect.mysql.ast.expr.MySqlUserName;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.*;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement.TableSpaceOption;
|
||||
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateUserStatement.UserSpecification;
|
||||
import com.alibaba.druid.sql.visitor.ExportParameterVisitor;
|
||||
import com.alibaba.druid.sql.visitor.ExportParameterVisitorUtils;
|
||||
import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils;
|
||||
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;
|
||||
import com.alibaba.druid.sql.visitor.*;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -81,7 +78,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
}
|
||||
|
||||
public void configFromProperty(Properties properties) {
|
||||
if (parameterized) {
|
||||
if (isEnabled(VisitorFeature.OutputParameterized)) {
|
||||
String property = properties.getProperty("druid.parameterized.shardingSupport");
|
||||
if ("true".equals(property)) {
|
||||
this.setShardingSupport(true);
|
||||
@@ -92,7 +89,8 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
}
|
||||
|
||||
public boolean isShardingSupport() {
|
||||
return parameterized && shardingSupport;
|
||||
return isEnabled(VisitorFeature.OutputParameterized)
|
||||
&& shardingSupport;
|
||||
}
|
||||
|
||||
public void setShardingSupport(boolean shardingSupport) {
|
||||
@@ -573,7 +571,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
}
|
||||
|
||||
try {
|
||||
if (this.parameterized
|
||||
if (this.isEnabled(VisitorFeature.OutputParameterized)
|
||||
&& ParameterizedOutputVisitorUtils.checkParameterize(x)) {
|
||||
this.appender.append('?');
|
||||
incrementReplaceCunt();
|
||||
@@ -1001,7 +999,7 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
|
||||
protected void printValuesList(List<SQLInsertStatement.ValuesClause> valuesList) {
|
||||
|
||||
if (parameterized) {
|
||||
if (isEnabled(VisitorFeature.OutputParameterized)) {
|
||||
print0(ucase ? "VALUES " : "values ");
|
||||
incrementIndent();
|
||||
valuesList.get(0).accept(this);
|
||||
@@ -2774,7 +2772,8 @@ public class MySqlOutputVisitor extends SQLASTOutputVisitor implements MySqlASTV
|
||||
|
||||
@Override
|
||||
public boolean visit(MySqlCharExpr x) {
|
||||
if (parameterized && ParameterizedOutputVisitorUtils.checkParameterize(x)) {
|
||||
if (isEnabled(VisitorFeature.OutputParameterized)
|
||||
&& ParameterizedOutputVisitorUtils.checkParameterize(x)) {
|
||||
print('?');
|
||||
incrementReplaceCunt();
|
||||
if (this instanceof ExportParameterVisitor || this.parameters != null) {
|
||||
|
||||
+4
-7
@@ -22,26 +22,23 @@ import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNCharExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNullExpr;
|
||||
import com.alibaba.druid.sql.ast.expr.SQLNumberExpr;
|
||||
import com.alibaba.druid.sql.visitor.ExportParameterVisitor;
|
||||
import com.alibaba.druid.sql.visitor.ExportParameterVisitorUtils;
|
||||
import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils;
|
||||
import com.alibaba.druid.sql.visitor.ParameterizedVisitor;
|
||||
import com.alibaba.druid.sql.visitor.*;
|
||||
|
||||
public class OracleParameterizedOutputVisitor extends OracleOutputVisitor implements ParameterizedVisitor {
|
||||
|
||||
public OracleParameterizedOutputVisitor(){
|
||||
this(new StringBuilder());
|
||||
this.parameterized = true;
|
||||
this.config(VisitorFeature.OutputParameterized, true);
|
||||
}
|
||||
|
||||
public OracleParameterizedOutputVisitor(Appendable appender){
|
||||
super(appender);
|
||||
this.parameterized = true;
|
||||
this.config(VisitorFeature.OutputParameterized, true);
|
||||
}
|
||||
|
||||
public OracleParameterizedOutputVisitor(Appendable appender, boolean printPostSemi){
|
||||
super(appender, printPostSemi);
|
||||
this.parameterized = true;
|
||||
this.config(VisitorFeature.OutputParameterized, true);
|
||||
}
|
||||
|
||||
public boolean visit(SQLBinaryOpExpr x) {
|
||||
|
||||
@@ -47,7 +47,7 @@ import com.alibaba.druid.util.StringUtils;
|
||||
* @author wenshao [szujobs@hotmail.com]
|
||||
*/
|
||||
public class Lexer {
|
||||
|
||||
protected int features;
|
||||
protected final String text;
|
||||
protected int pos;
|
||||
protected int mark;
|
||||
@@ -1644,4 +1644,12 @@ public class Lexer {
|
||||
public int getPosColumn() {
|
||||
return posColumn;
|
||||
}
|
||||
|
||||
public void config(SQLParserFeature feature, boolean state) {
|
||||
features = SQLParserFeature.config(features, feature, state);
|
||||
}
|
||||
|
||||
public final boolean isEnabled(SQLParserFeature feature) {
|
||||
return SQLParserFeature.isEnabled(this.features, feature);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ public class SQLParser {
|
||||
|
||||
protected String dbType;
|
||||
|
||||
|
||||
|
||||
public SQLParser(String sql, String dbType){
|
||||
this(new Lexer(sql, null, dbType), dbType);
|
||||
this.lexer.nextToken();
|
||||
@@ -316,4 +318,11 @@ public class SQLParser {
|
||||
}
|
||||
}
|
||||
|
||||
public void config(SQLParserFeature feature, boolean state) {
|
||||
this.lexer.config(feature, state);
|
||||
}
|
||||
|
||||
public final boolean isEnabled(SQLParserFeature feature) {
|
||||
return lexer.isEnabled(feature);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.sql.parser;
|
||||
|
||||
public enum SQLParserFeature {
|
||||
KeepInsertValueClauseOriginalString
|
||||
;
|
||||
|
||||
private SQLParserFeature(){
|
||||
mask = (1 << ordinal());
|
||||
}
|
||||
|
||||
public final int mask;
|
||||
|
||||
|
||||
public static boolean isEnabled(int features, SQLParserFeature feature) {
|
||||
return (features & feature.mask) != 0;
|
||||
}
|
||||
|
||||
public static int config(int features, SQLParserFeature feature, boolean state) {
|
||||
if (state) {
|
||||
features |= feature.mask;
|
||||
} else {
|
||||
features &= ~feature.mask;
|
||||
}
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
public static int of(SQLParserFeature[] features) {
|
||||
if (features == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int value = 0;
|
||||
|
||||
for (SQLParserFeature feature: features) {
|
||||
value |= feature.mask;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,7 @@ import com.alibaba.druid.sql.dialect.oracle.ast.OracleSegmentAttributes;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDeclareStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreatePackageStatement;
|
||||
import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleForStatement;
|
||||
import com.alibaba.druid.sql.visitor.functions.Ucase;
|
||||
import com.alibaba.druid.util.JdbcConstants;
|
||||
import com.alibaba.druid.util.JdbcUtils;
|
||||
|
||||
@@ -54,7 +55,6 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
protected final Appendable appender;
|
||||
private String indent = "\t";
|
||||
protected int indentCount = 0;
|
||||
private boolean prettyFormat = true;
|
||||
protected boolean ucase = true;
|
||||
protected int selectListNumberOfLine = 5;
|
||||
|
||||
@@ -72,17 +72,19 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
|
||||
protected int replaceCount;
|
||||
|
||||
protected boolean parameterized = false;
|
||||
protected boolean parameterizedMergeInList = false;
|
||||
|
||||
protected boolean shardingSupport = false;
|
||||
|
||||
protected transient int lines = 0;
|
||||
|
||||
protected boolean desensitize = false;
|
||||
|
||||
protected Boolean printStatementAfterSemi = defaultPrintStatementAfterSemi;
|
||||
|
||||
{
|
||||
features |= VisitorFeature.OutputPrettyFormat.mask;
|
||||
}
|
||||
|
||||
public SQLASTOutputVisitor(Appendable appender){
|
||||
this.appender = appender;
|
||||
}
|
||||
@@ -94,7 +96,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
|
||||
public SQLASTOutputVisitor(Appendable appender, boolean parameterized){
|
||||
this.appender = appender;
|
||||
this.parameterized = parameterized;
|
||||
this.config(VisitorFeature.OutputParameterized, parameterized);
|
||||
}
|
||||
|
||||
public int getReplaceCount() {
|
||||
@@ -125,11 +127,11 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
}
|
||||
|
||||
public boolean isDesensitize() {
|
||||
return desensitize;
|
||||
return isEnabled(VisitorFeature.OutputDesensitize);
|
||||
}
|
||||
|
||||
public void setDesensitize(boolean desensitize) {
|
||||
this.desensitize = desensitize;
|
||||
config(VisitorFeature.OutputDesensitize, desensitize);
|
||||
}
|
||||
|
||||
public Set<String> getTables() {
|
||||
@@ -158,11 +160,11 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
}
|
||||
|
||||
public boolean isPrettyFormat() {
|
||||
return prettyFormat;
|
||||
return isEnabled(VisitorFeature.OutputPrettyFormat);
|
||||
}
|
||||
|
||||
public void setPrettyFormat(boolean prettyFormat) {
|
||||
this.prettyFormat = prettyFormat;
|
||||
config(VisitorFeature.OutputPrettyFormat, prettyFormat);
|
||||
}
|
||||
|
||||
public void decrementIndent() {
|
||||
@@ -174,11 +176,11 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
}
|
||||
|
||||
public boolean isParameterized() {
|
||||
return parameterized;
|
||||
return isEnabled(VisitorFeature.OutputParameterized);
|
||||
}
|
||||
|
||||
public void setParameterized(boolean parameterized) {
|
||||
this.parameterized = parameterized;
|
||||
config(VisitorFeature.OutputParameterized, parameterized);
|
||||
}
|
||||
|
||||
public boolean isParameterizedMergeInList() {
|
||||
@@ -315,7 +317,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
}
|
||||
|
||||
protected void printSelectList(List<SQLSelectItem> selectList) {
|
||||
incrementIndent();
|
||||
this.indentCount++;
|
||||
for (int i = 0, lineItemCount = 0, size = selectList.size()
|
||||
; i < size; ++i, ++lineItemCount) {
|
||||
SQLSelectItem selectItem = selectList.get(i);
|
||||
@@ -361,7 +363,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
printlnComment(selectItem.getAfterCommentsDirect());
|
||||
}
|
||||
}
|
||||
decrementIndent();
|
||||
this.indentCount--;
|
||||
}
|
||||
|
||||
protected void printlnAndAccept(List<? extends SQLObject> nodes, String seperator) {
|
||||
@@ -420,7 +422,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
}
|
||||
|
||||
public boolean visit(SQLBinaryOpExpr x) {
|
||||
if (this.parameterized) {
|
||||
if (this.isEnabled(VisitorFeature.OutputParameterized)) {
|
||||
x = ParameterizedOutputVisitorUtils.merge(this, x);
|
||||
}
|
||||
|
||||
@@ -701,7 +703,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
}
|
||||
|
||||
public boolean visit(SQLCharExpr x) {
|
||||
if (this.parameterized
|
||||
if (this.isEnabled(VisitorFeature.OutputParameterized)
|
||||
&& ParameterizedOutputVisitorUtils.checkParameterize(x)) {
|
||||
print('?');
|
||||
incrementReplaceCunt();
|
||||
@@ -789,7 +791,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
|
||||
public boolean visit(SQLIdentifierExpr x) {
|
||||
final String name = x.getName();
|
||||
if (!parameterized) {
|
||||
if (!this.isEnabled(VisitorFeature.OutputParameterized)) {
|
||||
print0(x.getName());
|
||||
return false;
|
||||
}
|
||||
@@ -798,7 +800,8 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
}
|
||||
|
||||
private boolean printName(SQLName x, String name) {
|
||||
boolean shardingSupport = this.shardingSupport && parameterized;
|
||||
boolean shardingSupport = this.shardingSupport
|
||||
&& this.isEnabled(VisitorFeature.OutputParameterized);
|
||||
return printName(x, name, shardingSupport);
|
||||
}
|
||||
|
||||
@@ -885,7 +888,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
}
|
||||
|
||||
public boolean visit(SQLInListExpr x) {
|
||||
if (this.parameterized) {
|
||||
if (this.isEnabled(VisitorFeature.OutputParameterized)) {
|
||||
List<SQLExpr> targetList = x.getTargetList();
|
||||
|
||||
boolean allLiteral = true;
|
||||
@@ -995,7 +998,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.parameterized
|
||||
if (this.isEnabled(VisitorFeature.OutputParameterized)
|
||||
&& ParameterizedOutputVisitorUtils.checkParameterize(x)) {
|
||||
if (!ParameterizedOutputVisitorUtils.checkParameterize(x)) {
|
||||
print(val);
|
||||
@@ -1032,7 +1035,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
}
|
||||
SQLExpr param = x.getParameters().get(i);
|
||||
|
||||
if (parameterized) {
|
||||
if (isEnabled(VisitorFeature.OutputParameterized)) {
|
||||
if (size == 2 && i == 1 && param instanceof SQLCharExpr) {
|
||||
if (JdbcUtils.ORACLE.equals(dbType)) {
|
||||
if ("TO_CHAR".equalsIgnoreCase(function)
|
||||
@@ -1126,7 +1129,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
}
|
||||
|
||||
public boolean visit(SQLNCharExpr x) {
|
||||
if (this.parameterized
|
||||
if (this.isEnabled(VisitorFeature.OutputParameterized)
|
||||
&& ParameterizedOutputVisitorUtils.checkParameterize(x)) {
|
||||
print('?');
|
||||
incrementReplaceCunt();
|
||||
@@ -1170,7 +1173,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
}
|
||||
|
||||
public boolean visit(SQLNullExpr x) {
|
||||
if (this.parameterized
|
||||
if (this.isEnabled(VisitorFeature.OutputParameterized)
|
||||
&& ParameterizedOutputVisitorUtils.checkParameterize(x)) {
|
||||
SQLObject parent = x.getParent();
|
||||
if (parent instanceof ValuesClause) {
|
||||
@@ -1189,7 +1192,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
}
|
||||
|
||||
public boolean visit(SQLNumberExpr x) {
|
||||
if (this.parameterized
|
||||
if (this.isEnabled(VisitorFeature.OutputParameterized)
|
||||
&& ParameterizedOutputVisitorUtils.checkParameterize(x)) {
|
||||
print('?');
|
||||
incrementReplaceCunt();
|
||||
@@ -1578,7 +1581,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
addTable(expr.toString());
|
||||
}
|
||||
|
||||
if (desensitize) {
|
||||
if (isEnabled(VisitorFeature.OutputDesensitize)) {
|
||||
SQLExpr owner = null;
|
||||
String ident = null;
|
||||
if (expr instanceof SQLIdentifierExpr) {
|
||||
@@ -2208,7 +2211,8 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
|
||||
@Override
|
||||
public boolean visit(SQLHexExpr x) {
|
||||
if (this.parameterized && ParameterizedOutputVisitorUtils.checkParameterize(x)) {
|
||||
if (this.isEnabled(VisitorFeature.OutputParameterized)
|
||||
&& ParameterizedOutputVisitorUtils.checkParameterize(x)) {
|
||||
print('?');
|
||||
incrementReplaceCunt();
|
||||
|
||||
@@ -2348,6 +2352,13 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
|
||||
@Override
|
||||
public boolean visit(ValuesClause x) {
|
||||
if ((!isEnabled(VisitorFeature.OutputParameterized))
|
||||
&& isEnabled(VisitorFeature.OutputUseInsertValueClauseOriginalString)
|
||||
&& x.getOriginalString() != null) {
|
||||
print0(x.getOriginalString());
|
||||
return false;
|
||||
}
|
||||
|
||||
print('(');
|
||||
this.indentCount++;
|
||||
|
||||
@@ -4839,4 +4850,16 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet
|
||||
public void setPrintStatementAfterSemi(Boolean printStatementAfterSemi) {
|
||||
this.printStatementAfterSemi = printStatementAfterSemi;
|
||||
}
|
||||
|
||||
public void config(VisitorFeature feature, boolean state) {
|
||||
super.config(feature, state);
|
||||
if (feature == VisitorFeature.OutputUCase) {
|
||||
this.ucase = state;
|
||||
}
|
||||
}
|
||||
|
||||
public void setFeatures(int features) {
|
||||
super.setFeatures(features);
|
||||
this.ucase = isEnabled(VisitorFeature.OutputUCase);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,8 +24,10 @@ import com.alibaba.druid.sql.ast.statement.SQLMergeStatement.MergeUpdateClause;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLWhileStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLDeclareStatement;
|
||||
import com.alibaba.druid.sql.ast.statement.SQLCommitStatement;
|
||||
import com.alibaba.druid.sql.parser.SQLParserFeature;
|
||||
|
||||
public class SQLASTVisitorAdapter implements SQLASTVisitor {
|
||||
protected int features;
|
||||
|
||||
public void endVisit(SQLAllColumnExpr x) {
|
||||
}
|
||||
@@ -1672,4 +1674,20 @@ public class SQLASTVisitorAdapter implements SQLASTVisitor {
|
||||
public void endVisit(SQLCreateMaterializedViewStatement x) {
|
||||
|
||||
}
|
||||
|
||||
public void config(VisitorFeature feature, boolean state) {
|
||||
features = VisitorFeature.config(features, feature, state);
|
||||
}
|
||||
|
||||
public final boolean isEnabled(VisitorFeature feature) {
|
||||
return VisitorFeature.isEnabled(this.features, feature);
|
||||
}
|
||||
|
||||
public int getFeatures() {
|
||||
return features;
|
||||
}
|
||||
|
||||
public void setFeatures(int features) {
|
||||
this.features = features;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.sql.visitor;
|
||||
|
||||
public enum VisitorFeature {
|
||||
OutputUCase,
|
||||
OutputPrettyFormat,
|
||||
OutputParameterized,
|
||||
OutputDesensitize,
|
||||
OutputUseInsertValueClauseOriginalString
|
||||
|
||||
;
|
||||
|
||||
private VisitorFeature(){
|
||||
mask = (1 << ordinal());
|
||||
}
|
||||
|
||||
public final int mask;
|
||||
|
||||
|
||||
public static boolean isEnabled(int features, VisitorFeature feature) {
|
||||
return (features & feature.mask) != 0;
|
||||
}
|
||||
|
||||
public static int config(int features, VisitorFeature feature, boolean state) {
|
||||
if (state) {
|
||||
features |= feature.mask;
|
||||
} else {
|
||||
features &= ~feature.mask;
|
||||
}
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
public static int of(VisitorFeature... features) {
|
||||
if (features == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int value = 0;
|
||||
|
||||
for (VisitorFeature feature: features) {
|
||||
value |= feature.mask;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user