From 178de15fac9b9d085bed8bae05360dd7a27715bc Mon Sep 17 00:00:00 2001 From: qxo Date: Tue, 31 May 2016 19:42:43 +0800 Subject: [PATCH] =?UTF-8?q?bug=E4=BF=AE=E5=A4=8D=E5=8F=8A=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E5=A2=9E=E5=BC=BA=EF=BC=9A=E7=9B=B8=E5=BA=94ExportPar?= =?UTF-8?q?ameterVisitor=E5=AE=9E=E7=8E=B0=E7=B1=BB=E6=89=A9=E5=B1=95?= =?UTF-8?q?=E7=9B=B8=E5=BA=94=E7=9A=84ParameterizedOutputVisitor=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E7=B1=BB=EF=BC=8C=E4=BB=A5=E4=BF=AE=E6=AD=A3ExportPar?= =?UTF-8?q?ameterVisitor=E7=8E=B0=E6=9C=89=E5=AE=9E=E7=8E=B0=E7=9A=84?= =?UTF-8?q?=E5=8A=9F=E8=83=BDbug=E5=B9=B6=E5=87=8F=E5=B0=91=E9=87=8D?= =?UTF-8?q?=E5=A4=8D=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../visitor/DB2ExportParameterVisitor.java | 50 +++++++++++++-- .../visitor/MySqlExportParameterVisitor.java | 55 +++++++++++++--- .../visitor/OracleExportParameterVisitor.java | 43 +++++++++++-- .../visitor/PGExportParameterVisitor.java | 42 ++++++++++-- .../MSSQLServerExportParameterVisitor.java | 45 +++++++++++-- .../visitor/ExportParameterVisitorUtils.java | 43 ++++++++++++- .../ExportParameterizedOutputVisitor.java | 50 +++++++++++++++ .../ParameterizedOutputVisitorUtils.java | 30 +++++++++ .../sql/visitor/SQLASTOutputVisitor.java | 2 +- ...ExportAndParameterizedVisitorTestCase.java | 64 +++++++++++++++++++ 10 files changed, 392 insertions(+), 32 deletions(-) create mode 100644 src/main/java/com/alibaba/druid/sql/visitor/ExportParameterizedOutputVisitor.java create mode 100644 src/test/java/com/alibaba/druid/sql/parser/ExportAndParameterizedVisitorTestCase.java diff --git a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ExportParameterVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ExportParameterVisitor.java index 71cabb80be..73b310c953 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ExportParameterVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/db2/visitor/DB2ExportParameterVisitor.java @@ -28,58 +28,94 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectItem; import com.alibaba.druid.sql.visitor.ExportParameterVisitor; import com.alibaba.druid.sql.visitor.ExportParameterVisitorUtils; -public class DB2ExportParameterVisitor extends DB2ASTVisitorAdapter implements ExportParameterVisitor { +public class DB2ExportParameterVisitor extends DB2ParameterizedOutputVisitor implements ExportParameterVisitor { - private final List parameters; - public DB2ExportParameterVisitor(){ + /** + * true= if require parameterized sql output + */ + private final boolean requireParameterizedOutput; + + public DB2ExportParameterVisitor(final List parameters,final Appendable appender,final boolean wantParameterizedOutput){ + super(appender); + this.parameters = parameters; + this.requireParameterizedOutput = wantParameterizedOutput; + } + + public DB2ExportParameterVisitor() { this(new ArrayList()); } - public DB2ExportParameterVisitor(List parameters){ - this.parameters = parameters; + public DB2ExportParameterVisitor(final List parameters){ + this(parameters,new StringBuilder(),false); } + public DB2ExportParameterVisitor(final Appendable appender) { + this(new ArrayList(),appender,true); + } + + public List getParameters() { return parameters; } @Override public boolean visit(SQLSelectItem x) { + if(requireParameterizedOutput){ + return super.visit(x); + } return false; } @Override public boolean visit(SQLOrderBy x) { + if(requireParameterizedOutput){ + return super.visit(x); + } return false; } @Override public boolean visit(SQLSelectGroupByClause x) { + if(requireParameterizedOutput){ + return super.visit(x); + } return false; } @Override public boolean visit(SQLMethodInvokeExpr x) { + if(requireParameterizedOutput){ + return super.visit(x); + } ExportParameterVisitorUtils.exportParamterAndAccept(this.parameters, x.getParameters()); - return true; } @Override public boolean visit(SQLInListExpr x) { + if(requireParameterizedOutput){ + return super.visit(x); + } + ExportParameterVisitorUtils.exportParamterAndAccept(this.parameters, x.getTargetList()); - return true; } @Override public boolean visit(SQLBetweenExpr x) { + if(requireParameterizedOutput){ + return super.visit(x); + } + ExportParameterVisitorUtils.exportParameter(this.parameters, x); return true; } public boolean visit(SQLBinaryOpExpr x) { + if(requireParameterizedOutput){ + return super.visit(x); + } ExportParameterVisitorUtils.exportParameter(this.parameters, x); return true; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlExportParameterVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlExportParameterVisitor.java index 6ad074f8a6..7fbccf08f9 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlExportParameterVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/mysql/visitor/MySqlExportParameterVisitor.java @@ -29,51 +29,83 @@ import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlSelectQueryBlock.L import com.alibaba.druid.sql.visitor.ExportParameterVisitor; import com.alibaba.druid.sql.visitor.ExportParameterVisitorUtils; -public class MySqlExportParameterVisitor extends MySqlASTVisitorAdapter implements ExportParameterVisitor { +public class MySqlExportParameterVisitor extends MySqlParameterizedOutputVisitor implements ExportParameterVisitor { + + /** + * true= if require parameterized sql output + */ + private final boolean requireParameterizedOutput; + + public MySqlExportParameterVisitor(final List parameters,final Appendable appender,final boolean wantParameterizedOutput){ + super(appender); + this.parameters = parameters; + this.requireParameterizedOutput = wantParameterizedOutput; + } - private final List parameters; - public MySqlExportParameterVisitor() { this(new ArrayList()); } - public MySqlExportParameterVisitor(List parameters){ - this.parameters = parameters; + public MySqlExportParameterVisitor(final List parameters){ + this(parameters,new StringBuilder(),false); + } + + public MySqlExportParameterVisitor(final Appendable appender) { + this(new ArrayList(),appender,true); } public List getParameters() { return parameters; } + @Override - public boolean visit(SQLSelectItem x) { + public boolean visit(final SQLSelectItem x) { + if(requireParameterizedOutput){ + return super.visit(x); + } return false; } @Override public boolean visit(Limit x) { + if(requireParameterizedOutput){ + return super.visit(x); + } return false; } @Override public boolean visit(SQLOrderBy x) { + if(requireParameterizedOutput){ + return super.visit(x); + } return false; } @Override public boolean visit(SQLSelectGroupByClause x) { + if(requireParameterizedOutput){ + return super.visit(x); + } return false; } @Override public boolean visit(SQLMethodInvokeExpr x) { + if(requireParameterizedOutput){ + return super.visit(x); + } + ExportParameterVisitorUtils.exportParamterAndAccept(this.parameters, x.getParameters()); - return true; } @Override public boolean visit(SQLInListExpr x) { + if(requireParameterizedOutput){ + return super.visit(x); + } ExportParameterVisitorUtils.exportParamterAndAccept(this.parameters, x.getTargetList()); return true; @@ -81,13 +113,18 @@ public class MySqlExportParameterVisitor extends MySqlASTVisitorAdapter implemen @Override public boolean visit(SQLBetweenExpr x) { + if(requireParameterizedOutput){ + return super.visit(x); + } ExportParameterVisitorUtils.exportParameter(this.parameters, x); return true; } public boolean visit(SQLBinaryOpExpr x) { + if(requireParameterizedOutput){ + return super.visit(x); + } ExportParameterVisitorUtils.exportParameter(this.parameters, x); return true; } - -} +} \ No newline at end of file diff --git a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleExportParameterVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleExportParameterVisitor.java index 82cdfded7f..321d44bfbd 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleExportParameterVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleExportParameterVisitor.java @@ -28,16 +28,29 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectItem; import com.alibaba.druid.sql.visitor.ExportParameterVisitor; import com.alibaba.druid.sql.visitor.ExportParameterVisitorUtils; -public class OracleExportParameterVisitor extends OracleASTVisitorAdapter implements ExportParameterVisitor { +public class OracleExportParameterVisitor extends OracleParameterizedOutputVisitor implements ExportParameterVisitor { - private final List parameters; + /** + * true= if require parameterized sql output + */ + private final boolean requireParameterizedOutput; + + public OracleExportParameterVisitor(List parameters,Appendable appender,final boolean wantParameterizedOutput){ + super(appender,false); + this.parameters = parameters; + this.requireParameterizedOutput = wantParameterizedOutput; + } public OracleExportParameterVisitor() { this(new ArrayList()); } public OracleExportParameterVisitor(List parameters){ - this.parameters = parameters; + this(parameters,new StringBuilder(),true); + } + + public OracleExportParameterVisitor(final Appendable appender) { + this(new ArrayList(),appender,true); } public List getParameters() { @@ -46,40 +59,60 @@ public class OracleExportParameterVisitor extends OracleASTVisitorAdapter implem @Override public boolean visit(SQLSelectItem x) { + if(requireParameterizedOutput){ + return super.visit(x); + } return false; } @Override public boolean visit(SQLOrderBy x) { + if(requireParameterizedOutput){ + return super.visit(x); + } return false; } @Override public boolean visit(SQLSelectGroupByClause x) { + if(requireParameterizedOutput){ + return super.visit(x); + } return false; } @Override public boolean visit(SQLMethodInvokeExpr x) { + if(requireParameterizedOutput){ + return super.visit(x); + } + ExportParameterVisitorUtils.exportParamterAndAccept(this.parameters, x.getParameters()); - return true; } @Override public boolean visit(SQLInListExpr x) { + if(requireParameterizedOutput){ + return super.visit(x); + } ExportParameterVisitorUtils.exportParamterAndAccept(this.parameters, x.getTargetList()); - return true; } @Override public boolean visit(SQLBetweenExpr x) { + if(requireParameterizedOutput){ + return super.visit(x); + } ExportParameterVisitorUtils.exportParameter(this.parameters, x); return true; } public boolean visit(SQLBinaryOpExpr x) { + if(requireParameterizedOutput){ + return super.visit(x); + } ExportParameterVisitorUtils.exportParameter(this.parameters, x); return true; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGExportParameterVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGExportParameterVisitor.java index 6a4d8acf79..50d820d1ee 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGExportParameterVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/postgresql/visitor/PGExportParameterVisitor.java @@ -28,39 +28,64 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectItem; import com.alibaba.druid.sql.visitor.ExportParameterVisitor; import com.alibaba.druid.sql.visitor.ExportParameterVisitorUtils; -public class PGExportParameterVisitor extends PGASTVisitorAdapter implements ExportParameterVisitor { +public class PGExportParameterVisitor extends PGParameterizedOutputVisitor implements ExportParameterVisitor { - private final List parameters; + /** + * true= if require parameterized sql output + */ + private final boolean requireParameterizedOutput; + + public PGExportParameterVisitor(final List parameters,final Appendable appender,final boolean wantParameterizedOutput){ + super(appender); + this.parameters = parameters; + this.requireParameterizedOutput = wantParameterizedOutput; + } public PGExportParameterVisitor() { this(new ArrayList()); } - public PGExportParameterVisitor(List parameters){ - this.parameters = parameters; + public PGExportParameterVisitor(final List parameters){ + this(parameters,new StringBuilder(),false); } + public PGExportParameterVisitor(final Appendable appender) { + this(new ArrayList(),appender,true); + } + public List getParameters() { return parameters; } @Override public boolean visit(SQLSelectItem x) { + if(requireParameterizedOutput){ + return super.visit(x); + } return false; } @Override public boolean visit(SQLOrderBy x) { + if(requireParameterizedOutput){ + return super.visit(x); + } return false; } @Override public boolean visit(SQLSelectGroupByClause x) { + if(requireParameterizedOutput){ + return super.visit(x); + } return false; } @Override public boolean visit(SQLMethodInvokeExpr x) { + if(requireParameterizedOutput){ + return super.visit(x); + } ExportParameterVisitorUtils.exportParamterAndAccept(this.parameters, x.getParameters()); return true; @@ -68,6 +93,9 @@ public class PGExportParameterVisitor extends PGASTVisitorAdapter implements Exp @Override public boolean visit(SQLInListExpr x) { + if(requireParameterizedOutput){ + return super.visit(x); + } ExportParameterVisitorUtils.exportParamterAndAccept(this.parameters, x.getTargetList()); return true; @@ -75,11 +103,17 @@ public class PGExportParameterVisitor extends PGASTVisitorAdapter implements Exp @Override public boolean visit(SQLBetweenExpr x) { + if(requireParameterizedOutput){ + return super.visit(x); + } ExportParameterVisitorUtils.exportParameter(this.parameters, x); return true; } public boolean visit(SQLBinaryOpExpr x) { + if(requireParameterizedOutput){ + return super.visit(x); + } ExportParameterVisitorUtils.exportParameter(this.parameters, x); return true; } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/MSSQLServerExportParameterVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/MSSQLServerExportParameterVisitor.java index cb4ba31cf6..3cd037f080 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/MSSQLServerExportParameterVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/MSSQLServerExportParameterVisitor.java @@ -28,39 +28,65 @@ import com.alibaba.druid.sql.ast.statement.SQLSelectItem; import com.alibaba.druid.sql.visitor.ExportParameterVisitor; import com.alibaba.druid.sql.visitor.ExportParameterVisitorUtils; -public class MSSQLServerExportParameterVisitor extends SQLServerASTVisitorAdapter implements ExportParameterVisitor { +public class MSSQLServerExportParameterVisitor extends SQLServerParameterizedOutputVisitor implements ExportParameterVisitor { + + /** + * true= if require parameterized sql output + */ + private final boolean requireParameterizedOutput; + + public MSSQLServerExportParameterVisitor(final List parameters,final Appendable appender,final boolean wantParameterizedOutput){ + super(appender); + this.parameters = parameters; + this.requireParameterizedOutput = wantParameterizedOutput; + } - private final List parameters; - public MSSQLServerExportParameterVisitor() { this(new ArrayList()); } - public MSSQLServerExportParameterVisitor(List parameters){ - this.parameters = parameters; + public MSSQLServerExportParameterVisitor(final List parameters){ + this(parameters,new StringBuilder(),false); } + public MSSQLServerExportParameterVisitor(final Appendable appender) { + this(new ArrayList(),appender,true); + } + public List getParameters() { return parameters; } @Override public boolean visit(SQLSelectItem x) { + if(requireParameterizedOutput){ + return super.visit(x); + } return false; } @Override public boolean visit(SQLOrderBy x) { + if(requireParameterizedOutput){ + return super.visit(x); + } return false; } @Override public boolean visit(SQLSelectGroupByClause x) { + if(requireParameterizedOutput){ + return super.visit(x); + } return false; } @Override public boolean visit(SQLMethodInvokeExpr x) { + if(requireParameterizedOutput){ + return super.visit(x); + } + ExportParameterVisitorUtils.exportParamterAndAccept(this.parameters, x.getParameters()); return true; @@ -68,6 +94,9 @@ public class MSSQLServerExportParameterVisitor extends SQLServerASTVisitorAdapte @Override public boolean visit(SQLInListExpr x) { + if(requireParameterizedOutput){ + return super.visit(x); + } ExportParameterVisitorUtils.exportParamterAndAccept(this.parameters, x.getTargetList()); return true; @@ -75,11 +104,17 @@ public class MSSQLServerExportParameterVisitor extends SQLServerASTVisitorAdapte @Override public boolean visit(SQLBetweenExpr x) { + if(requireParameterizedOutput){ + return super.visit(x); + } ExportParameterVisitorUtils.exportParameter(this.parameters, x); return true; } public boolean visit(SQLBinaryOpExpr x) { + if(requireParameterizedOutput){ + return super.visit(x); + } ExportParameterVisitorUtils.exportParameter(this.parameters, x); return true; } 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 2a252fd88f..884898e320 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/ExportParameterVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/ExportParameterVisitorUtils.java @@ -25,8 +25,49 @@ import com.alibaba.druid.sql.ast.expr.SQLCharExpr; import com.alibaba.druid.sql.ast.expr.SQLLiteralExpr; import com.alibaba.druid.sql.ast.expr.SQLNumericLiteralExpr; import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; +import com.alibaba.druid.sql.dialect.db2.visitor.DB2ExportParameterVisitor; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlExportParameterVisitor; +import com.alibaba.druid.sql.dialect.oracle.visitor.OracleExportParameterVisitor; +import com.alibaba.druid.sql.dialect.postgresql.visitor.PGExportParameterVisitor; +import com.alibaba.druid.sql.dialect.sqlserver.visitor.MSSQLServerExportParameterVisitor; +import com.alibaba.druid.util.JdbcUtils; -public class ExportParameterVisitorUtils { +public final class ExportParameterVisitorUtils { + + //private for util class not need new instance + private ExportParameterVisitorUtils() { + super(); + } + + public static ExportParameterVisitor createExportParameterVisitor(final Appendable out ,final String dbType) { + + if (JdbcUtils.MYSQL.equals(dbType)) { + return new MySqlExportParameterVisitor(out); + } + if (JdbcUtils.ORACLE.equals(dbType) || JdbcUtils.ALI_ORACLE.equals(dbType)) { + return new OracleExportParameterVisitor(out); + } + if (JdbcUtils.DB2.equals(dbType)) { + return new DB2ExportParameterVisitor(out); + } + + if (JdbcUtils.MARIADB.equals(dbType)) { + return new MySqlExportParameterVisitor(out); + } + + if (JdbcUtils.H2.equals(dbType)) { + return new MySqlExportParameterVisitor(out); + } + if (JdbcUtils.POSTGRESQL.equals(dbType)) { + return new PGExportParameterVisitor(out); + } + if (JdbcUtils.SQL_SERVER.equals(dbType) || JdbcUtils.JTDS.equals(dbType)) { + return new MSSQLServerExportParameterVisitor(out); + } + return new ExportParameterizedOutputVisitor(out); + } + + public static boolean exportParamterAndAccept(final List parameters, List list) { for (int i = 0, size = list.size(); i < size; ++i) { diff --git a/src/main/java/com/alibaba/druid/sql/visitor/ExportParameterizedOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/visitor/ExportParameterizedOutputVisitor.java new file mode 100644 index 0000000000..1b8fb381af --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/visitor/ExportParameterizedOutputVisitor.java @@ -0,0 +1,50 @@ +/* + * 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.sql.visitor; + +import java.util.ArrayList; +import java.util.List; + +public class ExportParameterizedOutputVisitor extends ParameterizedOutputVisitor implements ExportParameterVisitor { + + /** + * true= if require parameterized sql output + */ + private final boolean requireParameterizedOutput; + + public ExportParameterizedOutputVisitor(final List parameters,final Appendable appender,final boolean wantParameterizedOutput){ + super(appender); + this.parameters = parameters; + this.requireParameterizedOutput = wantParameterizedOutput; + } + + public ExportParameterizedOutputVisitor() { + this(new ArrayList()); + } + + public ExportParameterizedOutputVisitor(final List parameters){ + this(parameters,new StringBuilder(),false); + } + + public ExportParameterizedOutputVisitor(final Appendable appender) { + this(new ArrayList(),appender,true); + } + + + public List getParameters() { + return parameters; + } +} 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 3651788ff4..66e2c7008d 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java @@ -123,6 +123,9 @@ public class ParameterizedOutputVisitorUtils { if (changed) { v.incrementReplaceCunt(); + if( v instanceof ExportParameterVisitor){ + ExportParameterVisitorUtils.exportParameter(((ExportParameterVisitor)v).getParameters(), x); + } } return false; @@ -135,6 +138,10 @@ public class ParameterizedOutputVisitorUtils { v.print('?'); v.incrementReplaceCunt(); + + if( v instanceof ExportParameterVisitor){ + ExportParameterVisitorUtils.exportParameter(((ExportParameterVisitor)v).getParameters(), x); + } return false; } @@ -145,15 +152,22 @@ public class ParameterizedOutputVisitorUtils { v.print('?'); v.incrementReplaceCunt(); + if( v instanceof ExportParameterVisitor){ + ExportParameterVisitorUtils.exportParameter(((ExportParameterVisitor)v).getParameters(), x); + } return false; } public static boolean visit(ParameterizedVisitor v, SQLCharExpr x) { v.print('?'); v.incrementReplaceCunt(); + if( v instanceof ExportParameterVisitor){ + ExportParameterVisitorUtils.exportParameter(((ExportParameterVisitor)v).getParameters(), x); + } return false; } + public static boolean checkParameterize(SQLObject x) { if (Boolean.TRUE.equals(x.getAttribute(ParameterizedOutputVisitorUtils.ATTR_PARAMS_SKIP))) { return false; @@ -176,6 +190,10 @@ public class ParameterizedOutputVisitorUtils { public static boolean visit(ParameterizedVisitor v, SQLNCharExpr x) { v.print('?'); v.incrementReplaceCunt(); + + if( v instanceof ExportParameterVisitor){ + ExportParameterVisitorUtils.exportParameter(((ExportParameterVisitor)v).getParameters(), x); + } return false; } @@ -192,18 +210,30 @@ public class ParameterizedOutputVisitorUtils { v.print('?'); v.incrementReplaceCunt(); + + if( v instanceof ExportParameterVisitor){ + ExportParameterVisitorUtils.exportParameter(((ExportParameterVisitor)v).getParameters(), x); + } return false; } public static boolean visit(ParameterizedVisitor v, SQLVariantRefExpr x) { v.print('?'); v.incrementReplaceCunt(); + + if( v instanceof ExportParameterVisitor){ + ExportParameterVisitorUtils.exportParameter(((ExportParameterVisitor)v).getParameters(), x); + } return false; } public static boolean visit(ParameterizedVisitor v, SQLHexExpr x) { v.print('?'); v.incrementReplaceCunt(); + + if( v instanceof ExportParameterVisitor){ + ExportParameterVisitorUtils.exportParameter(((ExportParameterVisitor)v).getParameters(), x); + } return false; } 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 1ae550dc21..0091adda71 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -100,7 +100,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Printab protected boolean groupItemSingleLine = false; - private List parameters; + protected List parameters; protected String dbType; diff --git a/src/test/java/com/alibaba/druid/sql/parser/ExportAndParameterizedVisitorTestCase.java b/src/test/java/com/alibaba/druid/sql/parser/ExportAndParameterizedVisitorTestCase.java new file mode 100644 index 0000000000..653ad0f97a --- /dev/null +++ b/src/test/java/com/alibaba/druid/sql/parser/ExportAndParameterizedVisitorTestCase.java @@ -0,0 +1,64 @@ +/* + * 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.sql.parser; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.visitor.ExportParameterVisitor; +import com.alibaba.druid.sql.visitor.ExportParameterVisitorUtils; +import com.alibaba.druid.sql.visitor.ParameterizedVisitor; +import com.alibaba.druid.util.JdbcConstants; +import com.alibaba.druid.util.JdbcUtils; + +public class ExportAndParameterizedVisitorTestCase extends TestCase { + + public void testParameterizedVisitor() { + // final String sql = + // "insert into tab01(a,b,c) values('a1','bXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1',5)"; + Object[][] sqlAndExpectedCases = { { "insert into tab01(a,b,c) values('a1','b1',5)", 3, "a1" }, + { "select * from tab01 where a=1 and b='b1'", 2, 1 }, + { "update tab01 set d='d1' where a=1 and b='b1'", 3, "d1" }, + { "delete from tab01 where a=1 and b='b1'", 2, 1.0 } }; + + String[] dbTypes = { "mysql", "oracle", "db2" ,JdbcConstants.POSTGRESQL,JdbcUtils.JTDS,"not-found"}; + // String[] dbTypes = { JdbcUtils.JTDS}; + for (String dbType : dbTypes) { + + System.out.println("dbType:"+dbType); + for (Object[] arr : sqlAndExpectedCases) { + + final String sql = (String) arr[0]; + StringBuilder out = new StringBuilder(); + + final SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); + final ParameterizedVisitor pVisitor = (ParameterizedVisitor) ExportParameterVisitorUtils.createExportParameterVisitor(out, dbType); + final SQLStatement parseStatement = parser.parseStatement(); + parseStatement.accept(pVisitor); + // final ExportParameterVisitor vistor2 = new MySqlExportParameterVisitor(); + // parseStatement.accept(vistor2); + final ExportParameterVisitor vistor2 = (ExportParameterVisitor) pVisitor; + System.out.println("before:" + sql); + System.out.println("after:" + out); + System.out.println("size:" + vistor2.getParameters()); + final int expectedSize = (Integer) arr[1]; + Assert.assertEquals(expectedSize, vistor2.getParameters().size()); + } + } + } +}