diff --git a/src/main/java/com/alibaba/druid/sql/SQLUtils.java b/src/main/java/com/alibaba/druid/sql/SQLUtils.java index 25e42c5d62..16af336f4a 100644 --- a/src/main/java/com/alibaba/druid/sql/SQLUtils.java +++ b/src/main/java/com/alibaba/druid/sql/SQLUtils.java @@ -183,6 +183,10 @@ public class SQLUtils { if (JdbcUtils.SQL_SERVER.equals(dbType)) { return new SQLServerOutputVisitor(out); } + + if (JdbcUtils.JTDS.equals(dbType)) { + return new SQLServerOutputVisitor(out); + } if (JdbcUtils.H2.equals(dbType)) { return new MySqlOutputVisitor(out); @@ -211,6 +215,10 @@ public class SQLUtils { if (JdbcUtils.SQL_SERVER.equals(dbType)) { return new SQLServerSchemaStatVisitor(); } + + if (JdbcUtils.JTDS.equals(dbType)) { + return new SQLServerSchemaStatVisitor(); + } if (JdbcUtils.H2.equals(dbType)) { return new MySqlSchemaStatVisitor(); diff --git a/src/main/java/com/alibaba/druid/sql/ast/SQLOver.java b/src/main/java/com/alibaba/druid/sql/ast/SQLOver.java index b7ef73fcfc..e2d1822ab3 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/SQLOver.java +++ b/src/main/java/com/alibaba/druid/sql/ast/SQLOver.java @@ -5,6 +5,21 @@ import java.util.List; import com.alibaba.druid.sql.visitor.SQLASTVisitor; +/* + * Copyright 1999-2011 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. + */ public class SQLOver extends SQLObjectImpl { private static final long serialVersionUID = 1L; diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerParameterizedOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerParameterizedOutputVisitor.java new file mode 100644 index 0000000000..83ec6f9377 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerParameterizedOutputVisitor.java @@ -0,0 +1,83 @@ +/* + * Copyright 1999-2011 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.dialect.sqlserver.visitor; + +import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; +import com.alibaba.druid.sql.ast.expr.SQLCharExpr; +import com.alibaba.druid.sql.ast.expr.SQLInListExpr; +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.ParameterizedOutputVisitorUtils; + +public class SQLServerParameterizedOutputVisitor extends SQLServerOutputVisitor { + + public SQLServerParameterizedOutputVisitor(Appendable appender){ + super(appender); + } + + public boolean visit(SQLInListExpr x) { + return ParameterizedOutputVisitorUtils.visit(this, x); + } + + public boolean visit(SQLBinaryOpExpr x) { + x = ParameterizedOutputVisitorUtils.merge(x); + + return super.visit(x); + } + + public boolean visit(SQLNullExpr x) { + print('?'); + return false; + } + + public boolean visit(SQLIntegerExpr x) { + if (Boolean.TRUE.equals(x.getAttribute(ParameterizedOutputVisitorUtils.ATTR_PARAMS_SKIP))) { + return super.visit(x); + } + + print('?'); + return false; + } + + public boolean visit(SQLNumberExpr x) { + if (Boolean.TRUE.equals(x.getAttribute(ParameterizedOutputVisitorUtils.ATTR_PARAMS_SKIP))) { + return super.visit(x); + } + + print('?'); + return false; + } + + public boolean visit(SQLCharExpr x) { + if (Boolean.TRUE.equals(x.getAttribute(ParameterizedOutputVisitorUtils.ATTR_PARAMS_SKIP))) { + return super.visit(x); + } + + print('?'); + return false; + } + + public boolean visit(SQLNCharExpr x) { + if (Boolean.TRUE.equals(x.getAttribute(ParameterizedOutputVisitorUtils.ATTR_PARAMS_SKIP))) { + return super.visit(x); + } + + print('?'); + return false; + } +} diff --git a/src/main/java/com/alibaba/druid/sql/parser/SQLParserUtils.java b/src/main/java/com/alibaba/druid/sql/parser/SQLParserUtils.java index c4cd436f92..b8c04b40a3 100644 --- a/src/main/java/com/alibaba/druid/sql/parser/SQLParserUtils.java +++ b/src/main/java/com/alibaba/druid/sql/parser/SQLParserUtils.java @@ -43,6 +43,10 @@ public class SQLParserUtils { if (JdbcUtils.SQL_SERVER.equals(dbType)) { return new SQLServerStatementParser(sql); } + + if (JdbcUtils.JTDS.equals(dbType)) { + return new SQLServerStatementParser(sql); + } if (JdbcUtils.H2.equals(dbType)) { return new MySqlStatementParser(sql); @@ -71,6 +75,10 @@ public class SQLParserUtils { if (JdbcUtils.SQL_SERVER.equals(dbType)) { return new SQLServerExprParser(sql); } + + if (JdbcUtils.JTDS.equals(dbType)) { + return new SQLServerExprParser(sql); + } return new SQLExprParser(sql); } 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 895565a705..88cf78eadb 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/ParameterizedOutputVisitorUtils.java @@ -27,6 +27,7 @@ import com.alibaba.druid.sql.ast.expr.SQLVariantRefExpr; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlParameterizedOutputVisitor; import com.alibaba.druid.sql.dialect.oracle.visitor.OracleParameterizedOutputVisitor; import com.alibaba.druid.sql.dialect.postgresql.visitor.PGParameterizedOutputVisitor; +import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerParameterizedOutputVisitor; import com.alibaba.druid.sql.parser.SQLParserUtils; import com.alibaba.druid.sql.parser.SQLStatementParser; import com.alibaba.druid.util.JdbcUtils; @@ -63,6 +64,10 @@ public class ParameterizedOutputVisitorUtils { if (JdbcUtils.POSTGRESQL.equals(dbType)) { return new PGParameterizedOutputVisitor(out); } + + if (JdbcUtils.SQL_SERVER.equals(dbType) || JdbcUtils.JTDS.equals(dbType)) { + return new SQLServerParameterizedOutputVisitor(out); + } return new ParameterizedOutputVisitor(out); } diff --git a/src/main/java/com/alibaba/druid/wall/WallFilter.java b/src/main/java/com/alibaba/druid/wall/WallFilter.java index c81a6802aa..590358e148 100644 --- a/src/main/java/com/alibaba/druid/wall/WallFilter.java +++ b/src/main/java/com/alibaba/druid/wall/WallFilter.java @@ -75,7 +75,7 @@ public class WallFilter extends FilterAdapter implements WallFilterMBean { } provider = new OracleWallProvider(config); - } else if (JdbcUtils.SQL_SERVER.equals(dbType)) { + } else if (JdbcUtils.SQL_SERVER.equals(dbType) || JdbcUtils.JTDS.equals(dbType)) { if (config == null) { config = new WallConfig(SQLServerProvider.DEFAULT_CONFIG_DIR); } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerRowNumberTest2.java b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerRowNumberTest2.java new file mode 100644 index 0000000000..dfa6d284ee --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerRowNumberTest2.java @@ -0,0 +1,53 @@ +/* + * Copyright 1999-2011 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.sqlserver; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.sqlserver.parser.SQLServerStatementParser; +import com.alibaba.druid.sql.test.TestUtils; + +public class SQLServerRowNumberTest2 extends TestCase { + + public void test_isEmpty() throws Exception { + String sql = "SELECT * FROM (" + + // + " SELECT ROW_NUMBER() OVER (ORDER BY FAlertDate Desc, FAlertLevel, FAlertType) AS RowNumber, *" + + // + " from monitor_business" + // + " where FRemoveAlert = ?" + // + " ) AS temp_table" + // + " WHERE RowNumber BETWEEN ? AND ?"; + + String expect = "SELECT *" + + "\nFROM (SELECT ROW_NUMBER() OVER () ORDER BY FAlertDate DESC, FAlertLevel, FAlertType AS RowNumber, *" + + "\n\tFROM monitor_business" + + "\n\tWHERE FRemoveAlert = ?" + + "\n\t) temp_table" + + "\nWHERE RowNumber BETWEEN ? AND ?"; + + SQLServerStatementParser parser = new SQLServerStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + + String text = TestUtils.outputSqlServer(stmt); + + Assert.assertEquals(expect, text); + + System.out.println(text); + } +}