From 1be6d04a9afd038e6ba483e70fc202bbd20d8b21 Mon Sep 17 00:00:00 2001 From: xiaoma20082008 <915567926@qq.com> Date: Thu, 2 Aug 2018 22:15:45 +0800 Subject: [PATCH] feat:1.h2 database's insert statement support `set` statement,2: support `char` instead of 'java.lang.Character' when SQLASTOutputVisitor visit prepared sql and the inputParameters has a char value --- .../dialect/h2/parser/H2StatementParser.java | 40 ++++++++++++++++++- .../sql/visitor/SQLASTOutputVisitor.java | 29 ++++++++------ .../druid/bvt/sql/h2/H2_InsertTest_0.java | 24 +++++++++++ ...ySqlParameterizedOutputVisitorTest_56.java | 23 ++++++++++- 4 files changed, 101 insertions(+), 15 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/h2/H2_InsertTest_0.java 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 46e734d63e..8716d52d4d 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 07ca4fd4ba..8caf426349 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -15,28 +15,16 @@ */ package com.alibaba.druid.sql.visitor; -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 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; @@ -47,6 +35,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 { @@ -2159,6 +2156,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()); + } + }