diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/SQLServerObject.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/SQLServerObject.java index a2804d9743..1280e64f80 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/SQLServerObject.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/SQLServerObject.java @@ -15,8 +15,9 @@ */ package com.alibaba.druid.sql.dialect.sqlserver.ast; +import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerASTVisitor; import com.alibaba.druid.sql.dialect.transact.ast.TransactSQLObject; public interface SQLServerObject extends TransactSQLObject { - + public void accept0(SQLServerASTVisitor visitor); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/stmt/SQLServerInsertStatement.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/stmt/SQLServerInsertStatement.java new file mode 100644 index 0000000000..85329a6ce6 --- /dev/null +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/ast/stmt/SQLServerInsertStatement.java @@ -0,0 +1,52 @@ +package com.alibaba.druid.sql.dialect.sqlserver.ast.stmt; + +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; +import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerObject; +import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerASTVisitor; +import com.alibaba.druid.sql.visitor.SQLASTVisitor; + +public class SQLServerInsertStatement extends SQLInsertStatement implements SQLServerObject { + + private static final long serialVersionUID = 2652393792927901563L; + + private List valuesList = new ArrayList(); + + public ValuesClause getValues() { + if (valuesList.size() == 0) { + return null; + } + return valuesList.get(0); + } + + public void setValues(ValuesClause values) { + if (valuesList.size() == 0) { + valuesList.add(values); + } else { + valuesList.set(0, values); + } + } + + public List getValuesList() { + return valuesList; + } + + @Override + protected void accept0(SQLASTVisitor visitor) { + this.accept0((SQLServerASTVisitor) visitor); + } + + @Override + public void accept0(SQLServerASTVisitor visitor) { + if (visitor.visit(this)) { + this.acceptChild(visitor, getTableSource()); + this.acceptChild(visitor, getColumns()); + this.acceptChild(visitor, getValuesList()); + this.acceptChild(visitor, getQuery()); + } + + visitor.endVisit(this); + } +} diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitor.java index 5474e187a1..1f07cb136f 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitor.java @@ -18,6 +18,7 @@ package com.alibaba.druid.sql.dialect.sqlserver.visitor; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock; import com.alibaba.druid.sql.dialect.sqlserver.ast.Top; import com.alibaba.druid.sql.dialect.sqlserver.ast.expr.SQLServerObjectReferenceExpr; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement; import com.alibaba.druid.sql.visitor.SQLASTVisitor; public interface SQLServerASTVisitor extends SQLASTVisitor { @@ -33,4 +34,8 @@ public interface SQLServerASTVisitor extends SQLASTVisitor { boolean visit(SQLServerObjectReferenceExpr x); void endVisit(SQLServerObjectReferenceExpr x); + + boolean visit(SQLServerInsertStatement x); + + void endVisit(SQLServerInsertStatement x); } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitorAdapter.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitorAdapter.java index 8fc7c82f29..699a8abbb6 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitorAdapter.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerASTVisitorAdapter.java @@ -18,6 +18,7 @@ package com.alibaba.druid.sql.dialect.sqlserver.visitor; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock; import com.alibaba.druid.sql.dialect.sqlserver.ast.Top; import com.alibaba.druid.sql.dialect.sqlserver.ast.expr.SQLServerObjectReferenceExpr; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement; import com.alibaba.druid.sql.visitor.SQLASTVisitorAdapter; public class SQLServerASTVisitorAdapter extends SQLASTVisitorAdapter implements SQLServerASTVisitor { @@ -52,4 +53,14 @@ public class SQLServerASTVisitorAdapter extends SQLASTVisitorAdapter implements } + @Override + public boolean visit(SQLServerInsertStatement x) { + return true; + } + + @Override + public void endVisit(SQLServerInsertStatement x) { + + } + } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerOutputVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerOutputVisitor.java index 01aac96844..460b137729 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerOutputVisitor.java @@ -19,6 +19,7 @@ import com.alibaba.druid.sql.ast.SQLSetQuantifier; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock; import com.alibaba.druid.sql.dialect.sqlserver.ast.Top; import com.alibaba.druid.sql.dialect.sqlserver.ast.expr.SQLServerObjectReferenceExpr; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement; import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; public class SQLServerOutputVisitor extends SQLASTOutputVisitor implements SQLServerASTVisitor { @@ -91,7 +92,54 @@ public class SQLServerOutputVisitor extends SQLASTOutputVisitor implements SQLSe @Override public void endVisit(SQLServerObjectReferenceExpr x) { - + + } + + @Override + public boolean visit(SQLServerInsertStatement x) { + print("INSERT INTO "); + + x.getTableName().accept(this); + + if (x.getColumns().size() > 0) { + incrementIndent(); + print(" ("); + for (int i = 0, size = x.getColumns().size(); i < size; ++i) { + if (i != 0) { + if (i % 5 == 0) { + println(); + } + print(", "); + } + + x.getColumns().get(i).accept(this); + } + print(")"); + decrementIndent(); + } + + if (x.getValuesList().size() != 0) { + println(); + print("VALUES "); + for (int i = 0, size = x.getValuesList().size(); i < size; ++i) { + if (i != 0) { + print(", "); + } + x.getValuesList().get(i).accept(this); + } + + } + + if (x.getQuery() != null) { + println(); + x.getQuery().accept(this); + } + return false; + } + + @Override + public void endVisit(SQLServerInsertStatement x) { + } } diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerSchemaStatVisitor.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerSchemaStatVisitor.java index 18df898487..a56c5c5ecb 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerSchemaStatVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/visitor/SQLServerSchemaStatVisitor.java @@ -15,10 +15,12 @@ */ package com.alibaba.druid.sql.dialect.sqlserver.visitor; +import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock; import com.alibaba.druid.sql.dialect.sqlserver.ast.SQLServerSelectQueryBlock; import com.alibaba.druid.sql.dialect.sqlserver.ast.Top; import com.alibaba.druid.sql.dialect.sqlserver.ast.expr.SQLServerObjectReferenceExpr; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement; import com.alibaba.druid.sql.visitor.SchemaStatVisitor; import com.alibaba.druid.util.JdbcUtils; @@ -60,5 +62,16 @@ public class SQLServerSchemaStatVisitor extends SchemaStatVisitor implements SQL } + @Override + public boolean visit(SQLServerInsertStatement x) { + this.visit((SQLInsertStatement) x); + return false; + } + + @Override + public void endVisit(SQLServerInsertStatement x) { + this.endVisit((SQLInsertStatement) x); + } + } diff --git a/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java b/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java index 179b5bc25f..83d0635bf5 100644 --- a/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java +++ b/src/main/java/com/alibaba/druid/wall/spi/SQLServerWallVisitor.java @@ -39,6 +39,7 @@ import com.alibaba.druid.sql.ast.statement.SQLTruncateStatement; import com.alibaba.druid.sql.ast.statement.SQLUnionQuery; import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; import com.alibaba.druid.sql.dialect.sqlserver.ast.expr.SQLServerObjectReferenceExpr; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement; import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerASTVisitor; import com.alibaba.druid.sql.dialect.sqlserver.visitor.SQLServerASTVisitorAdapter; import com.alibaba.druid.wall.Violation; @@ -232,4 +233,15 @@ public class SQLServerWallVisitor extends SQLServerASTVisitorAdapter implements } return true; } + + @Override + public boolean visit(SQLServerInsertStatement x) { + this.visit((SQLInsertStatement) x); + return false; + } + + @Override + public void endVisit(SQLServerInsertStatement x) { + this.endVisit((SQLInsertStatement) x); + } } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerInsertTest.java b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerInsertTest.java new file mode 100644 index 0000000000..cbebe25c5f --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerInsertTest.java @@ -0,0 +1,45 @@ +/* + * 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 SQLServerInsertTest extends TestCase { + + public void test_isEmpty() throws Exception { + String sql = "INSERT INTO Cities (Location)" + // + "VALUES ( CONVERT(Point, '12.3:46.2') );"; + + String expect = "INSERT INTO Cities" + // + "\n\t(Location)" + // + "\nVALUES" + // + "\n(CONVERT(Point, '12.3:46.2'))"; + + SQLServerStatementParser parser = new SQLServerStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + + String text = TestUtils.outputSqlServer(stmt); + + Assert.assertEquals(expect, text); + + System.out.println(text); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerInsertTest1.java b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerInsertTest1.java new file mode 100644 index 0000000000..9d66ffc8fd --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerInsertTest1.java @@ -0,0 +1,45 @@ +/* + * 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 SQLServerInsertTest1 extends TestCase { + + public void test_isEmpty() throws Exception { + String sql = "INSERT INTO Cities (Location)" + + "VALUES ( dbo.CreateNewPoint(x, y) );"; + + String expect = "INSERT INTO Cities" + // + "\n\t(Location)" + // + "\nVALUES" + // + "\n(dbo.CreateNewPoint(x, y))"; + + SQLServerStatementParser parser = new SQLServerStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + + String text = TestUtils.outputSqlServer(stmt); + + Assert.assertEquals(expect, text); + + System.out.println(text); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerInsertTest2.java b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerInsertTest2.java new file mode 100644 index 0000000000..1b21ec901c --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerInsertTest2.java @@ -0,0 +1,44 @@ +/* + * 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 SQLServerInsertTest2 extends TestCase { + + public void test_isEmpty() throws Exception { + String sql = "INSERT INTO Production.UnitMeasure " + // + "VALUES (N'F2', N'Square Feet', GETDATE());;"; + + String expect = "INSERT INTO Production.UnitMeasure" + // + "\nVALUES" + // + "\n(N'F2', N'Square Feet', GETDATE())"; + + SQLServerStatementParser parser = new SQLServerStatementParser(sql); + SQLStatement stmt = parser.parseStatementList().get(0); + + String text = TestUtils.outputSqlServer(stmt); + + Assert.assertEquals(expect, text); + + System.out.println(text); + } +}