Merge pull request #2735 from xiaoma20082008/master

h2数据库支持解析完整的insert set语句为单条以及参数化输出时支持char类型的数据
This commit is contained in:
温绍锦
2018-09-14 21:36:59 +08:00
committed by GitHub
4 changed files with 103 additions and 8 deletions
@@ -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;
}
}
}
}
@@ -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());
@@ -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<SQLStatement> sqlStatements = parser.parseStatementList();
Assert.assertEquals(1, sqlStatements.size());
}
}
@@ -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<SQLStatement> sqlStatements = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
Assert.assertTrue(sqlStatements.size() == 1);
StringBuilder out = new StringBuilder(sql.length());
MySqlOutputVisitor visitor = new MySqlOutputVisitor(out);
List<Object> parameters = new ArrayList<Object>(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());
}
}