From 29b4b3ea290390d9f33497d1be2e0ae3961dc307 Mon Sep 17 00:00:00 2001 From: wenshao Date: Sun, 12 Feb 2017 02:23:34 +0800 Subject: [PATCH] improved sql parameterized support. --- .../druid/sql/ast/expr/SQLInSubQueryExpr.java | 3 + .../sql/visitor/SQLASTOutputVisitor.java | 42 ++++++-- ...ySqlParameterizedOutputVisitorTest_30.java | 98 +++++++++++++++++++ ...ySqlParameterizedOutputVisitorTest_31.java | 95 ++++++++++++++++++ ...ySqlParameterizedOutputVisitorTest_32.java | 85 ++++++++++++++++ 5 files changed, 314 insertions(+), 9 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_30.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_31.java create mode 100644 src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_32.java diff --git a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLInSubQueryExpr.java b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLInSubQueryExpr.java index 18e5a82c4b..cdce963f35 100644 --- a/src/main/java/com/alibaba/druid/sql/ast/expr/SQLInSubQueryExpr.java +++ b/src/main/java/com/alibaba/druid/sql/ast/expr/SQLInSubQueryExpr.java @@ -47,6 +47,9 @@ public class SQLInSubQueryExpr extends SQLExprImpl implements Serializable { } public void setExpr(SQLExpr expr) { + if (expr != null) { + expr.setParent(this); + } this.expr = expr; } 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 0cb2aeb78d..6deb71bf8f 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -571,11 +571,34 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet } } if (isNumber) { - int start = quote ? 1 : 0; - String realName = name.substring(start, pos); - print0(realName); - incrementReplaceCunt(); - return false; + boolean isAlias = false; + for (SQLObject parent = x.getParent();parent != null; parent = parent.getParent()) { + if (parent instanceof SQLSelectQueryBlock) { + SQLTableSource from = ((SQLSelectQueryBlock) parent).getFrom(); + if (quote) { + String name2 = name.substring(1, name.length() - 1); + if (isTableSourceAlias(from, name, name2)) { + isAlias = true; + } + } else { + if (isTableSourceAlias(from, name)) { + isAlias = true; + } + } + break; + } + } + + if (!isAlias) { + int start = quote ? 1 : 0; + String realName = name.substring(start, pos); + print0(realName); + incrementReplaceCunt(); + return false; + } else { + print0(name); + return false; + } } } @@ -866,7 +889,7 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet for (SQLObject parent = x.getParent();parent != null; parent = parent.getParent()) { if (parent instanceof SQLSelectQueryBlock) { SQLTableSource from = ((SQLSelectQueryBlock) parent).getFrom(); - if (containsAlias(from, mapTableName, ownerName)) { + if (isTableSourceAlias(from, mapTableName, ownerName)) { mapTableName = null; } break; @@ -887,8 +910,9 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet return false; } - protected boolean containsAlias(SQLTableSource from, String... tableNames) { + protected boolean isTableSourceAlias(SQLTableSource from, String... tableNames) { String alias = from.getAlias(); + if (alias != null) { for (String tableName : tableNames) { if (alias.equalsIgnoreCase(tableName)) { @@ -907,8 +931,8 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet } if (from instanceof SQLJoinTableSource) { SQLJoinTableSource join = (SQLJoinTableSource) from; - return containsAlias(join.getLeft(), tableNames) - || containsAlias(join.getRight(), tableNames); + return isTableSourceAlias(join.getLeft(), tableNames) + || isTableSourceAlias(join.getRight(), tableNames); } return false; } diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_30.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_30.java new file mode 100644 index 0000000000..4195b6a677 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_30.java @@ -0,0 +1,98 @@ +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.parser.SQLParserUtils; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils; +import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; +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_30 extends TestCase { + public void test_for_parameterize() throws Exception { + final String dbType = JdbcConstants.MYSQL; + + + String sql = "/* 0a67bca314863468702364451e/0.3// */select `udata`.`id` as `id`,`udata`.`gmt_create` as `gmtCreate`,`udata`.`gmt_modified` as `gmtModified`,`udata`.`uid` as `userId`,`udata`.`user_nick` as `userNick`,`udata`.`user_type` as `userType`,`udata`.`aps` as `acPeSe`,`udata`.`rn` as `rn`,`udata`.`start_period_time` as `startPeriodTime`,`udata`.`ept` as `adTm`,`udata`.`status` as `status`,`udata`.`charging_period` as `chargingPeriod`,`udata`.`sn` as `sn`,`udata`.`cpd` as `chargingPeriodDesc`,`udata`.`task_total_num` as `taskTotalNum`,`udata`.`tcn` as `taCoNu`,`udata`.`task_type` as `taskType`,`udata`.`ilbu` as `isLaBiUs`" + + " from `udata_0888` `udata` where ((`udata`.`id` IN (" + + " (select MAX(`udata`.`id`) " + + " from `udata_0888` `udata` " + + " where ((`udata`.`uid` = 1039100792) AND (`udata`.`user_type` = 2) AND (`udata`.`start_period_time` <= '2017-01-01 00:00:00') AND (`udata`.`status` = 10) AND (`udata`.`charging_period` = 1) AND (`udata`.`task_type` = 1) AND (`udata`.`task_total_num` <= `udata`.`tcn`)) group by `udata`.`charging_period`,`udata`.`start_period_time`,`udata`.`ept`))) AND ((`udata`.`uid` = '1039100792') AND (`udata`.`user_type` = 2))) order by `udata`.`start_period_time` desc limit 0,6"; + + String psql = ParameterizedOutputVisitorUtils.parameterize(sql, dbType); + assertEquals("SELECT `udata`.`id` AS `id`, `udata`.`gmt_create` AS `gmtCreate`, `udata`.`gmt_modified` AS `gmtModified`, `udata`.`uid` AS `userId`, `udata`.`user_nick` AS `userNick`\n" + + "\t, `udata`.`user_type` AS `userType`, `udata`.`aps` AS `acPeSe`, `udata`.`rn` AS `rn`, `udata`.`start_period_time` AS `startPeriodTime`, `udata`.`ept` AS `adTm`\n" + + "\t, `udata`.`status` AS `status`, `udata`.`charging_period` AS `chargingPeriod`, `udata`.`sn` AS `sn`, `udata`.`cpd` AS `chargingPeriodDesc`, `udata`.`task_total_num` AS `taskTotalNum`\n" + + "\t, `udata`.`tcn` AS `taCoNu`, `udata`.`task_type` AS `taskType`, `udata`.`ilbu` AS `isLaBiUs`\n" + + "FROM udata `udata`\n" + + "WHERE `udata`.`id` IN (SELECT MAX(`udata`.`id`)\n" + + "\t\tFROM udata `udata`\n" + + "\t\tWHERE `udata`.`uid` = ?\n" + + "\t\t\tAND `udata`.`user_type` = ?\n" + + "\t\t\tAND `udata`.`start_period_time` <= ?\n" + + "\t\t\tAND `udata`.`status` = ?\n" + + "\t\t\tAND `udata`.`charging_period` = ?\n" + + "\t\t\tAND `udata`.`task_type` = ?\n" + + "\t\t\tAND `udata`.`task_total_num` <= `udata`.`tcn`\n" + + "\t\tGROUP BY `udata`.`charging_period`, `udata`.`start_period_time`, `udata`.`ept`)\n" + + "\tAND (`udata`.`uid` = ?\n" + + "\t\tAND `udata`.`user_type` = ?)\n" + + "ORDER BY `udata`.`start_period_time` DESC\n" + + "LIMIT ?, ?", psql); + + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); + List stmtList = parser.parseStatementList(); + + StringBuilder out = new StringBuilder(); + SQLASTOutputVisitor visitor = SQLUtils.createOutputVisitor(out, JdbcConstants.MYSQL); + List parameters = new ArrayList(); + visitor.setParameterized(true); + visitor.setParameterizedMergeInList(true); + visitor.setParameters(parameters); + visitor.setExportTables(true); + /*visitor.setPrettyFormat(false);*/ + + SQLStatement stmt = stmtList.get(0); + stmt.accept(visitor); + + // System.out.println(parameters); + assertEquals(10, parameters.size()); + + //SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(psql, dbType); + // List stmtList = parser.parseStatementList(); + SQLStatement pstmt = SQLUtils.parseStatements(psql, dbType).get(0); + + StringBuilder buf = new StringBuilder(); + SQLASTOutputVisitor visitor1 = SQLUtils.createOutputVisitor(buf, dbType); + visitor1.addTableMapping("udata", "udata_0888"); + visitor1.setParameters(visitor.getParameters()); + pstmt.accept(visitor1); + + assertEquals("SELECT `udata`.`id` AS `id`, `udata`.`gmt_create` AS `gmtCreate`, `udata`.`gmt_modified` AS `gmtModified`, `udata`.`uid` AS `userId`, `udata`.`user_nick` AS `userNick`\n" + + "\t, `udata`.`user_type` AS `userType`, `udata`.`aps` AS `acPeSe`, `udata`.`rn` AS `rn`, `udata`.`start_period_time` AS `startPeriodTime`, `udata`.`ept` AS `adTm`\n" + + "\t, `udata`.`status` AS `status`, `udata`.`charging_period` AS `chargingPeriod`, `udata`.`sn` AS `sn`, `udata`.`cpd` AS `chargingPeriodDesc`, `udata`.`task_total_num` AS `taskTotalNum`\n" + + "\t, `udata`.`tcn` AS `taCoNu`, `udata`.`task_type` AS `taskType`, `udata`.`ilbu` AS `isLaBiUs`\n" + + "FROM udata_0888 `udata`\n" + + "WHERE `udata`.`id` IN (SELECT MAX(`udata`.`id`)\n" + + "\t\tFROM udata_0888 `udata`\n" + + "\t\tWHERE `udata`.`uid` = 1039100792\n" + + "\t\t\tAND `udata`.`user_type` = 2\n" + + "\t\t\tAND `udata`.`start_period_time` <= '2017-01-01 00:00:00'\n" + + "\t\t\tAND `udata`.`status` = 10\n" + + "\t\t\tAND `udata`.`charging_period` = 1\n" + + "\t\t\tAND `udata`.`task_type` = 1\n" + + "\t\t\tAND `udata`.`task_total_num` <= `udata`.`tcn`\n" + + "\t\tGROUP BY `udata`.`charging_period`, `udata`.`start_period_time`, `udata`.`ept`)\n" + + "\tAND (`udata`.`uid` = '1039100792'\n" + + "\t\tAND `udata`.`user_type` = 2)\n" + + "ORDER BY `udata`.`start_period_time` DESC\n" + + "LIMIT 0, 6", buf.toString()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_31.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_31.java new file mode 100644 index 0000000000..b023bd1046 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_31.java @@ -0,0 +1,95 @@ +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.parser.SQLParserUtils; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils; +import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; +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_31 extends TestCase { + public void test_for_parameterize() throws Exception { + final String dbType = JdbcConstants.MYSQL; + + + String sql = "/* 0a67bca314863468702364451e/0.3// */select `udata`.`id` as `id`,`udata`.`gmt_create` as `gmtCreate`,`udata`.`gmt_modified` as `gmtModified`,`udata`.`uid` as `userId`,`udata`.`user_nick` as `userNick`,`udata`.`user_type` as `userType`,`udata`.`aps` as `acPeSe`,`udata`.`rn` as `rn`,`udata`.`start_period_time` as `startPeriodTime`,`udata`.`ept` as `adTm`,`udata`.`status` as `status`,`udata`.`charging_period` as `chargingPeriod`,`udata`.`sn` as `sn`,`udata`.`cpd` as `chargingPeriodDesc`,`udata`.`task_total_num` as `taskTotalNum`,`udata`.`tcn` as `taCoNu`,`udata`.`task_type` as `taskType`,`udata`.`ilbu` as `isLaBiUs`" + + " from `udata_0888` `udata` where ((`udata`.`id` IN ((select MAX(`udata`.`id`) from `udata_0888` `udata` where ((`udata`.`uid` = 1039100792) AND (`udata`.`user_type` = 2) AND (`udata`.`start_period_time` <= '2017-01-01 00:00:00') AND (`udata`.`status` = 10) AND (`udata`.`charging_period` = 1) AND (`udata`.`task_type` = 1) AND (`udata`.`task_total_num` <= `udata`.`tcn`)) group by `udata`.`charging_period`,`udata`.`start_period_time`,`udata`.`ept`))) AND ((`udata`.`uid` = '1039100792') AND (`udata`.`user_type` = 2))) order by `udata`.`start_period_time` desc limit 0,6"; + + String psql = ParameterizedOutputVisitorUtils.parameterize(sql, dbType); + assertEquals("SELECT `udata`.`id` AS `id`, `udata`.`gmt_create` AS `gmtCreate`, `udata`.`gmt_modified` AS `gmtModified`, `udata`.`uid` AS `userId`, `udata`.`user_nick` AS `userNick`\n" + + "\t, `udata`.`user_type` AS `userType`, `udata`.`aps` AS `acPeSe`, `udata`.`rn` AS `rn`, `udata`.`start_period_time` AS `startPeriodTime`, `udata`.`ept` AS `adTm`\n" + + "\t, `udata`.`status` AS `status`, `udata`.`charging_period` AS `chargingPeriod`, `udata`.`sn` AS `sn`, `udata`.`cpd` AS `chargingPeriodDesc`, `udata`.`task_total_num` AS `taskTotalNum`\n" + + "\t, `udata`.`tcn` AS `taCoNu`, `udata`.`task_type` AS `taskType`, `udata`.`ilbu` AS `isLaBiUs`\n" + + "FROM udata `udata`\n" + + "WHERE `udata`.`id` IN (SELECT MAX(`udata`.`id`)\n" + + "\t\tFROM udata `udata`\n" + + "\t\tWHERE `udata`.`uid` = ?\n" + + "\t\t\tAND `udata`.`user_type` = ?\n" + + "\t\t\tAND `udata`.`start_period_time` <= ?\n" + + "\t\t\tAND `udata`.`status` = ?\n" + + "\t\t\tAND `udata`.`charging_period` = ?\n" + + "\t\t\tAND `udata`.`task_type` = ?\n" + + "\t\t\tAND `udata`.`task_total_num` <= `udata`.`tcn`\n" + + "\t\tGROUP BY `udata`.`charging_period`, `udata`.`start_period_time`, `udata`.`ept`)\n" + + "\tAND (`udata`.`uid` = ?\n" + + "\t\tAND `udata`.`user_type` = ?)\n" + + "ORDER BY `udata`.`start_period_time` DESC\n" + + "LIMIT ?, ?", psql); + + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); + List stmtList = parser.parseStatementList(); + + StringBuilder out = new StringBuilder(); + SQLASTOutputVisitor visitor = SQLUtils.createOutputVisitor(out, JdbcConstants.MYSQL); + List parameters = new ArrayList(); + visitor.setParameterized(true); + visitor.setParameterizedMergeInList(true); + visitor.setParameters(parameters); + visitor.setExportTables(true); + /*visitor.setPrettyFormat(false);*/ + + SQLStatement stmt = stmtList.get(0); + stmt.accept(visitor); + + // System.out.println(parameters); + assertEquals(10, parameters.size()); + + //SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(psql, dbType); + // List stmtList = parser.parseStatementList(); + SQLStatement pstmt = SQLUtils.parseStatements(psql, dbType).get(0); + + StringBuilder buf = new StringBuilder(); + SQLASTOutputVisitor visitor1 = SQLUtils.createOutputVisitor(buf, dbType); + visitor1.addTableMapping("udata", "udata_0888"); + visitor1.setParameters(visitor.getParameters()); + pstmt.accept(visitor1); + + assertEquals("SELECT `udata`.`id` AS `id`, `udata`.`gmt_create` AS `gmtCreate`, `udata`.`gmt_modified` AS `gmtModified`, `udata`.`uid` AS `userId`, `udata`.`user_nick` AS `userNick`\n" + + "\t, `udata`.`user_type` AS `userType`, `udata`.`aps` AS `acPeSe`, `udata`.`rn` AS `rn`, `udata`.`start_period_time` AS `startPeriodTime`, `udata`.`ept` AS `adTm`\n" + + "\t, `udata`.`status` AS `status`, `udata`.`charging_period` AS `chargingPeriod`, `udata`.`sn` AS `sn`, `udata`.`cpd` AS `chargingPeriodDesc`, `udata`.`task_total_num` AS `taskTotalNum`\n" + + "\t, `udata`.`tcn` AS `taCoNu`, `udata`.`task_type` AS `taskType`, `udata`.`ilbu` AS `isLaBiUs`\n" + + "FROM udata_0888 `udata`\n" + + "WHERE `udata`.`id` IN (SELECT MAX(`udata`.`id`)\n" + + "\t\tFROM udata_0888 `udata`\n" + + "\t\tWHERE `udata`.`uid` = 1039100792\n" + + "\t\t\tAND `udata`.`user_type` = 2\n" + + "\t\t\tAND `udata`.`start_period_time` <= '2017-01-01 00:00:00'\n" + + "\t\t\tAND `udata`.`status` = 10\n" + + "\t\t\tAND `udata`.`charging_period` = 1\n" + + "\t\t\tAND `udata`.`task_type` = 1\n" + + "\t\t\tAND `udata`.`task_total_num` <= `udata`.`tcn`\n" + + "\t\tGROUP BY `udata`.`charging_period`, `udata`.`start_period_time`, `udata`.`ept`)\n" + + "\tAND (`udata`.`uid` = '1039100792'\n" + + "\t\tAND `udata`.`user_type` = 2)\n" + + "ORDER BY `udata`.`start_period_time` DESC\n" + + "LIMIT 0, 6", buf.toString()); + } +} diff --git a/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_32.java b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_32.java new file mode 100644 index 0000000000..27d801b9e2 --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/sql/mysql/param/MySqlParameterizedOutputVisitorTest_32.java @@ -0,0 +1,85 @@ +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.parser.SQLParserUtils; +import com.alibaba.druid.sql.parser.SQLStatementParser; +import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils; +import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor; +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_32 extends TestCase { + public void test_for_parameterize() throws Exception { + final String dbType = JdbcConstants.MYSQL; + + + String sql = "/* cds internal mark */select count(*) as count from (" + + "( select env_type from `tmall_miaoscm`.`miao_sale_ledger_0060` where `id` > 1 limit 136 )" + + " union all ( select env_type from `tmall_miaoscm`.`miao_sale_ledger_0060` where `id` > 2331 limit 136 )" + + ") as miao_sale_ledger_0060 where `miao_sale_ledger_0060`.`env_type` = 3"; + + String psql = ParameterizedOutputVisitorUtils.parameterize(sql, dbType); + assertEquals("SELECT COUNT(*) AS count\n" + + "FROM (\n" + + "\t(SELECT env_type\n" + + "\tFROM `tmall_miaoscm`.miao_sale_ledger\n" + + "\tWHERE `id` > ?\n" + + "\tLIMIT ?)\n" + + "\tUNION ALL\n" + + "\t(SELECT env_type\n" + + "\tFROM `tmall_miaoscm`.miao_sale_ledger\n" + + "\tWHERE `id` > ?\n" + + "\tLIMIT ?)\n" + + ") miao_sale_ledger_0060\n" + + "WHERE `miao_sale_ledger_0060`.`env_type` = ?", psql); + + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); + List stmtList = parser.parseStatementList(); + + StringBuilder out = new StringBuilder(); + SQLASTOutputVisitor visitor = SQLUtils.createOutputVisitor(out, JdbcConstants.MYSQL); + List parameters = new ArrayList(); + visitor.setParameterized(true); + visitor.setParameterizedMergeInList(true); + visitor.setParameters(parameters); + visitor.setExportTables(true); + /*visitor.setPrettyFormat(false);*/ + + SQLStatement stmt = stmtList.get(0); + stmt.accept(visitor); + + // System.out.println(parameters); + assertEquals(5, parameters.size()); + + //SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(psql, dbType); + // List stmtList = parser.parseStatementList(); + SQLStatement pstmt = SQLUtils.parseStatements(psql, dbType).get(0); + + StringBuilder buf = new StringBuilder(); + SQLASTOutputVisitor visitor1 = SQLUtils.createOutputVisitor(buf, dbType); + visitor1.addTableMapping("udata", "udata_0888"); + visitor1.setParameters(visitor.getParameters()); + pstmt.accept(visitor1); + + assertEquals("SELECT COUNT(*) AS count\n" + + "FROM (\n" + + "\t(SELECT env_type\n" + + "\tFROM `tmall_miaoscm`.miao_sale_ledger\n" + + "\tWHERE `id` > 1\n" + + "\tLIMIT 136)\n" + + "\tUNION ALL\n" + + "\t(SELECT env_type\n" + + "\tFROM `tmall_miaoscm`.miao_sale_ledger\n" + + "\tWHERE `id` > 2331\n" + + "\tLIMIT 136)\n" + + ") miao_sale_ledger_0060\n" + + "WHERE `miao_sale_ledger_0060`.`env_type` = 3", buf.toString()); + } +}