diff --git a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java index afc498c4e1..b29aa7d642 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/sqlserver/parser/SQLServerStatementParser.java @@ -15,9 +15,16 @@ */ package com.alibaba.druid.sql.dialect.sqlserver.parser; +import com.alibaba.druid.sql.ast.SQLName; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.ast.expr.SQLQueryExpr; +import com.alibaba.druid.sql.ast.statement.SQLInsertInto; +import com.alibaba.druid.sql.ast.statement.SQLInsertStatement; +import com.alibaba.druid.sql.dialect.sqlserver.ast.stmt.SQLServerInsertStatement; import com.alibaba.druid.sql.parser.Lexer; import com.alibaba.druid.sql.parser.SQLSelectParser; import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.sql.parser.Token; public class SQLServerStatementParser extends SQLStatementParser { @@ -32,5 +39,65 @@ public class SQLServerStatementParser extends SQLStatementParser { public SQLServerStatementParser(Lexer lexer){ super(new SQLServerExprParser(lexer)); } + + public SQLStatement parseInsert() { + SQLServerInsertStatement insertStatement = new SQLServerInsertStatement(); + if (lexer.token() == Token.INSERT) { + accept(Token.INSERT); + } + + parseInsert0(insertStatement); + return insertStatement; + } + + protected void parseInsert0(SQLInsertInto insert, boolean acceptSubQuery) { + SQLServerInsertStatement insertStatement = (SQLServerInsertStatement) insert; + + if (lexer.token() == Token.INTO) { + lexer.nextToken(); + + SQLName tableName = this.exprParser.name(); + insertStatement.setTableName(tableName); + + if (lexer.token() == Token.LITERAL_ALIAS) { + insertStatement.setAlias(as()); + } + + parseInsert0_hinits(insertStatement); + + if (lexer.token() == Token.IDENTIFIER) { + insertStatement.setAlias(lexer.stringVal()); + lexer.nextToken(); + } + } + + if (lexer.token() == (Token.LPAREN)) { + lexer.nextToken(); + this.exprParser.exprList(insertStatement.getColumns()); + accept(Token.RPAREN); + } + + if (lexer.token() == Token.VALUES) { + lexer.nextToken(); + + for (;;) { + accept(Token.LPAREN); + SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause(); + this.exprParser.exprList(values.getValues()); + insertStatement.getValuesList().add(values); + accept(Token.RPAREN); + + if (lexer.token() == Token.COMMA) { + lexer.nextToken(); + continue; + } else { + break; + } + } + } else if (acceptSubQuery && (lexer.token() == Token.SELECT || lexer.token() == Token.LPAREN)) { + SQLQueryExpr queryExpr = (SQLQueryExpr) this.exprParser.expr(); + insertStatement.setQuery(queryExpr.getSubQuery()); + } + } } 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 index 1b21ec901c..c3d36026b2 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerInsertTest2.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerInsertTest2.java @@ -24,13 +24,12 @@ 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());;"; + public void test_multi_values() throws Exception { + String sql = "INSERT INTO test (name)" + // + "VALUES (N'a'), (N'b'), (N'c')"; - String expect = "INSERT INTO Production.UnitMeasure" + // - "\nVALUES" + // - "\n(N'F2', N'Square Feet', GETDATE())"; + String expect = "INSERT INTO test (name)" + // + "\nVALUES (N'a'), (N'b'), (N'c')"; SQLServerStatementParser parser = new SQLServerStatementParser(sql); SQLStatement stmt = parser.parseStatementList().get(0); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerInsertTest3.java b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerInsertTest3.java new file mode 100644 index 0000000000..06b22bbbab --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/sqlserver/SQLServerInsertTest3.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 SQLServerInsertTest3 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); + } +}