From ac5edc6b363f4f1baf4cc0462067a96b162476ba Mon Sep 17 00:00:00 2001 From: wenshao Date: Sun, 4 Feb 2018 14:25:16 +0800 Subject: [PATCH] bug fixed for mysql parser. for issue #2114 --- .../visitor/ExportParameterVisitorUtils.java | 38 ++++++++++++---- .../sql/visitor/SQLASTOutputVisitor.java | 13 ++++++ ...lParameterizedOutputVisitorTest_60_in.java | 43 +++++++++++++++++++ 3 files changed, 85 insertions(+), 9 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_60_in.java diff --git a/src/main/java/com/alibaba/druid/sql/visitor/ExportParameterVisitorUtils.java b/src/main/java/com/alibaba/druid/sql/visitor/ExportParameterVisitorUtils.java index 033dabb0f5..edc239605d 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/ExportParameterVisitorUtils.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/ExportParameterVisitorUtils.java @@ -88,21 +88,41 @@ public final class ExportParameterVisitorUtils { if (param instanceof SQLCharExpr) { value = ((SQLCharExpr) param).getText(); replace = true; - } - - if (param instanceof SQLBooleanExpr) { + } else if (param instanceof SQLBooleanExpr) { value = ((SQLBooleanExpr) param).getBooleanValue(); replace = true; - } - - if (param instanceof SQLNumericLiteralExpr) { + } else if (param instanceof SQLNumericLiteralExpr) { value = ((SQLNumericLiteralExpr) param).getNumber(); replace = true; - } - - if (param instanceof SQLHexExpr) { + } else if (param instanceof SQLHexExpr) { value = ((SQLHexExpr) param).toBytes(); replace = true; + } else if (param instanceof SQLListExpr) { + SQLListExpr list = ((SQLListExpr) param); + + List listValues = new ArrayList(); + for (int i = 0; i < list.getItems().size(); i++) { + SQLExpr listItem = list.getItems().get(i); + + if (listItem instanceof SQLCharExpr) { + Object listValue = ((SQLCharExpr) listItem).getText(); + listValues.add(listValue); + } else if (listItem instanceof SQLBooleanExpr) { + Object listValue = ((SQLBooleanExpr) listItem).getBooleanValue(); + listValues.add(listValue); + } else if (listItem instanceof SQLNumericLiteralExpr) { + Object listValue = ((SQLNumericLiteralExpr) listItem).getNumber(); + listValues.add(listValue); + } else if (param instanceof SQLHexExpr) { + Object listValue = ((SQLHexExpr) listItem).toBytes(); + listValues.add(listValue); + } + } + + if (listValues.size() == list.getItems().size()) { + value = listValues; + replace = true; + } } if (replace) { 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 fc01aef900..14e4acbab2 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -1204,6 +1204,19 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet boolean allLiteral = true; for (SQLExpr item : targetList) { if (!(item instanceof SQLLiteralExpr || item instanceof SQLVariantRefExpr)) { + if (item instanceof SQLListExpr) { + SQLListExpr list = (SQLListExpr) item; + for (SQLExpr listItem : list.getItems()) { + if (!(listItem instanceof SQLLiteralExpr || listItem instanceof SQLVariantRefExpr)) { + allLiteral = false; + break; + } + } + if (allLiteral) { + break; + } + continue; + } allLiteral = false; break; } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_60_in.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_60_in.java new file mode 100644 index 0000000000..2fc5cd62e9 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_60_in.java @@ -0,0 +1,43 @@ +package com.alibaba.druid.bvt.sql.mysql.param; + +import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils; +import com.alibaba.druid.util.JdbcConstants; +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by wenshao on 16/8/23. + */ +public class MySqlParameterizedOutputVisitorTest_60_in extends TestCase { + public void test_for_parameterize() throws Exception { + + String sql = "select * from a where id in (1, 2,3)"; + + List params = new ArrayList(); + String psql = ParameterizedOutputVisitorUtils.parameterize(sql, JdbcConstants.MYSQL, params); + assertEquals("SELECT *\n" + + "FROM a\n" + + "WHERE id IN (?)", psql); + assertEquals(3, params.size()); + assertEquals(1, params.get(0)); + assertEquals(2, params.get(1)); + assertEquals(3, params.get(2)); + } + + public void test_for_parameterize_1() throws Exception { + + String sql = "select * from a where (id,userId) in ((1,2), (2,3),(3,4))"; + + List params = new ArrayList(); + String psql = ParameterizedOutputVisitorUtils.parameterize(sql, JdbcConstants.MYSQL, params); + assertEquals("SELECT *\n" + + "FROM a\n" + + "WHERE (id, userId) IN (?)", psql); + assertEquals(3, params.size()); + assertEquals("[1, 2]", params.get(0).toString()); + assertEquals("[2, 3]", params.get(1).toString()); + assertEquals("[3, 4]", params.get(2).toString()); + } +}