diff --git a/src/main/java/com/alibaba/druid/sql/dialect/h2/parser/H2StatementParser.java b/src/main/java/com/alibaba/druid/sql/dialect/h2/parser/H2StatementParser.java index e5ab475c5e..7cd69d21d2 100644 --- a/src/main/java/com/alibaba/druid/sql/dialect/h2/parser/H2StatementParser.java +++ b/src/main/java/com/alibaba/druid/sql/dialect/h2/parser/H2StatementParser.java @@ -18,11 +18,14 @@ package com.alibaba.druid.sql.dialect.h2.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.ast.statement.SQLReplaceStatement; import com.alibaba.druid.sql.ast.statement.SQLSelect; -import com.alibaba.druid.sql.parser.*; -import com.alibaba.druid.util.FnvHash; +import com.alibaba.druid.sql.parser.Lexer; +import com.alibaba.druid.sql.parser.SQLParserFeature; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.sql.parser.Token; import com.alibaba.druid.util.JdbcConstants; public class H2StatementParser extends SQLStatementParser { @@ -42,6 +45,7 @@ public class H2StatementParser extends SQLStatementParser { return new H2SelectParser(this.exprParser, selectListCache); } + @Override public SQLStatement parseMerge() { accept(Token.MERGE); accept(Token.INTO); @@ -74,4 +78,36 @@ public class H2StatementParser extends SQLStatementParser { return stmt; } + + @Override + protected void parseInsert0(SQLInsertInto insertStatement, boolean acceptSubQuery) { + super.parseInsert0(insertStatement, acceptSubQuery); + parseSetStatement(insertStatement); + } + + private void parseSetStatement(SQLInsertInto insertStatement) { + if (lexer.token() == Token.SET) { + lexer.nextToken(); + SQLInsertStatement.ValuesClause values = new SQLInsertStatement.ValuesClause(); + insertStatement.addValueCause(values); + + for (; ; ) { + SQLName name = this.exprParser.name(); + insertStatement.addColumn(name); + if (lexer.token() == Token.EQ) { + lexer.nextToken(); + } else { + accept(Token.COLONEQ); + } + values.addValue(this.exprParser.expr()); + + if (lexer.token() == Token.COMMA) { + lexer.nextToken(); + continue; + } + break; + } + } + } + } 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 ee145b1d0e..38979caf63 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -13,8 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.druid.sql.visitor; - +package com.alibaba.druid.sql.visitor import java.io.IOException; import java.io.InputStream; import java.io.Reader; @@ -26,19 +25,17 @@ import java.sql.NClob; import java.text.SimpleDateFormat; import java.util.*; + import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.*; import com.alibaba.druid.sql.ast.expr.*; import com.alibaba.druid.sql.ast.statement.*; -import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement.TriggerEvent; import com.alibaba.druid.sql.ast.statement.SQLCreateTriggerStatement.TriggerType; import com.alibaba.druid.sql.ast.statement.SQLInsertStatement.ValuesClause; import com.alibaba.druid.sql.ast.statement.SQLJoinTableSource.JoinType; import com.alibaba.druid.sql.ast.statement.SQLMergeStatement.MergeInsertClause; import com.alibaba.druid.sql.ast.statement.SQLMergeStatement.MergeUpdateClause; -import com.alibaba.druid.sql.ast.statement.SQLWhileStatement; 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.expr.OracleCursorExpr; import com.alibaba.druid.sql.dialect.oracle.ast.expr.OracleDatetimeExpr; import com.alibaba.druid.sql.dialect.oracle.ast.stmt.OracleCreatePackageStatement; @@ -49,6 +46,15 @@ import com.alibaba.druid.sql.dialect.oracle.parser.OracleProcedureDataType; import com.alibaba.druid.util.JdbcConstants; import com.alibaba.druid.util.JdbcUtils; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.sql.Blob; +import java.sql.Clob; +import java.sql.NClob; +import java.text.SimpleDateFormat; +import java.util.*; + import static com.alibaba.druid.util.Utils.getBoolean; public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements ParameterizedVisitor, PrintableVisitor { @@ -2270,6 +2276,14 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet return; } + if (param instanceof Character) { + print('\''); + print((Character) param); + print('\''); + return; + } + + if (param instanceof Number // || param instanceof Boolean) { print0(param.toString()); diff --git a/src/test/java/com/alibaba/druid/bvt/sql/h2/H2_InsertTest_0.java b/src/test/java/com/alibaba/druid/bvt/sql/h2/H2_InsertTest_0.java new file mode 100644 index 0000000000..91b133f655 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/h2/H2_InsertTest_0.java @@ -0,0 +1,24 @@ +package com.alibaba.druid.bvt.sql.h2; + +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.h2.parser.H2StatementParser; +import org.junit.Assert; +import org.junit.Test; + +import java.util.List; + +/** + * @author machunxiao + * @create 2018-08-02 + */ +public class H2_InsertTest_0 { + + @Test + public void test_insertSet() { + String sql = "insert into tb1 set name='n1',age=12,date='1990-11-11 12:12:12'"; + H2StatementParser parser = new H2StatementParser(sql); + List sqlStatements = parser.parseStatementList(); + Assert.assertEquals(1, sqlStatements.size()); + } + +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_56.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_56.java index 079ac31932..3c4676ea1e 100644 --- a/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_56.java +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_56.java @@ -2,14 +2,16 @@ package com.alibaba.druid.bvt.sql.mysql.param; import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlOutputVisitor; import com.alibaba.druid.sql.parser.SQLParserUtils; import com.alibaba.druid.sql.parser.SQLStatementParser; import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; import com.alibaba.druid.util.JdbcConstants; -import com.alibaba.druid.util.JdbcUtils; import junit.framework.TestCase; +import org.junit.Assert; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; /** @@ -62,4 +64,23 @@ public class MySqlParameterizedOutputVisitorTest_56 extends TestCase { String rsql = SQLUtils.format(psql, JdbcConstants.MYSQL, parameters); System.out.println(rsql); } + + public void test_for_parameter_char() throws Exception { + + String sql = "insert into t values(?,?,?)"; + + List sqlStatements = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL); + + Assert.assertTrue(sqlStatements.size() == 1); + + StringBuilder out = new StringBuilder(sql.length()); + MySqlOutputVisitor visitor = new MySqlOutputVisitor(out); + List parameters = new ArrayList(Arrays.asList('a', 'b', 'c')); + visitor.setInputParameters(parameters); + SQLStatement sqlStatement = sqlStatements.get(0); + sqlStatement.accept(visitor); + Assert.assertEquals("INSERT INTO t\n" + + "VALUES ('a', 'b', 'c')", out.toString()); + } + }