From 23e68d13cbf2a6cebd9b27a9d991b40d32f7775d Mon Sep 17 00:00:00 2001 From: wenshao Date: Thu, 22 Mar 2018 21:32:02 +0800 Subject: [PATCH] bug fixed for sql wall. for issue #2411 --- .../alibaba/druid/filter/FilterManager.java | 14 +++++- .../com/alibaba/druid/sql/PagerUtils.java | 45 ++++++++++++++--- .../sql/visitor/SQLASTOutputVisitor.java | 13 +++-- .../filter/wall/mysql/MySqlWallTest150.java | 50 +++++++++++++++++++ 4 files changed, 112 insertions(+), 10 deletions(-) create mode 100644 src/test/java/com/alibaba/druid/bvt/filter/wall/mysql/MySqlWallTest150.java diff --git a/src/main/java/com/alibaba/druid/filter/FilterManager.java b/src/main/java/com/alibaba/druid/filter/FilterManager.java index accc2936b3..2741b348e4 100644 --- a/src/main/java/com/alibaba/druid/filter/FilterManager.java +++ b/src/main/java/com/alibaba/druid/filter/FilterManager.java @@ -52,7 +52,17 @@ public class FilterManager { } public static final String getFilter(String alias) { - return aliasMap.get(alias) != null ? aliasMap.get(alias) : alias; + if (alias == null) { + return null; + } + + String filter = aliasMap.get(alias); + + if (filter == null && alias.length() < 128) { + filter = alias; + } + + return filter; } public static Properties loadFilterConfig() throws IOException { @@ -119,6 +129,8 @@ public class FilterManager { throw new SQLException("load managed jdbc driver event listener error. " + filterName, e); } catch (IllegalAccessException e) { throw new SQLException("load managed jdbc driver event listener error. " + filterName, e); + } catch (RuntimeException e) { + throw new SQLException("load managed jdbc driver event listener error. " + filterName, e); } filters.add(filter); diff --git a/src/main/java/com/alibaba/druid/sql/PagerUtils.java b/src/main/java/com/alibaba/druid/sql/PagerUtils.java index cfd3b0f5e0..2eef7cc8ec 100644 --- a/src/main/java/com/alibaba/druid/sql/PagerUtils.java +++ b/src/main/java/com/alibaba/druid/sql/PagerUtils.java @@ -93,15 +93,17 @@ public class PagerUtils { return limitSQLServer(select, dbType, offset, count, check); } - if (query instanceof SQLSelectQueryBlock) { - return limitQueryBlock(select, dbType, offset, count, check); - } - - throw new UnsupportedOperationException(); + return limitQueryBlock(select, dbType, offset, count, check); } private static boolean limitQueryBlock(SQLSelect select, String dbType, int offset, int count, boolean check) { - SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) select.getQuery(); + SQLSelectQuery query = select.getQuery(); + if (query instanceof SQLUnionQuery) { + SQLUnionQuery union = (SQLUnionQuery) query; + return limitUnion(union, dbType, offset, count, check); + } + + SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) query; if (JdbcConstants.MYSQL.equals(dbType) || // JdbcConstants.MARIADB.equals(dbType) || // JdbcConstants.H2.equals(dbType)) { @@ -400,6 +402,37 @@ public class PagerUtils { return true; } + private static boolean limitUnion(SQLUnionQuery queryBlock, String dbType, int offset, int count, boolean check) { + SQLLimit limit = queryBlock.getLimit(); + if (limit != null) { + if (offset > 0) { + limit.setOffset(new SQLIntegerExpr(offset)); + } + + if (check && limit.getRowCount() instanceof SQLNumericLiteralExpr) { + int rowCount = ((SQLNumericLiteralExpr) limit.getRowCount()).getNumber().intValue(); + if (rowCount <= count && offset <= 0) { + return false; + } + } else if (check && limit.getRowCount() instanceof SQLVariantRefExpr) { + return false; + } + + limit.setRowCount(new SQLIntegerExpr(count)); + } + + if (limit == null) { + limit = new SQLLimit(); + if (offset > 0) { + limit.setOffset(new SQLIntegerExpr(offset)); + } + limit.setRowCount(new SQLIntegerExpr(count)); + queryBlock.setLimit(limit); + } + + return true; + } + private static String count(SQLSelect select, String dbType) { if (select.getOrderBy() != null) { select.setOrderBy(null); 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 e1a88994c0..85e1711793 100644 --- a/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -2721,7 +2721,8 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet println(); SQLSelectQuery right = x.getRight(); - boolean needParen = x.getOrderBy() != null && !right.isBracket(); + SQLOrderBy orderBy = x.getOrderBy(); + boolean needParen = orderBy != null && !right.isBracket(); if (needParen) { print('('); @@ -2731,9 +2732,15 @@ public class SQLASTOutputVisitor extends SQLASTVisitorAdapter implements Paramet right.accept(this); } - if (x.getOrderBy() != null) { + if (orderBy != null) { println(); - x.getOrderBy().accept(this); + orderBy.accept(this); + } + + SQLLimit limit = x.getLimit(); + if (limit != null) { + println(); + limit.accept(this); } if (bracket) { diff --git a/src/test/java/com/alibaba/druid/bvt/filter/wall/mysql/MySqlWallTest150.java b/src/test/java/com/alibaba/druid/bvt/filter/wall/mysql/MySqlWallTest150.java new file mode 100644 index 0000000000..db947680fe --- /dev/null +++ b/src/test/java/com/alibaba/druid/bvt/filter/wall/mysql/MySqlWallTest150.java @@ -0,0 +1,50 @@ +package com.alibaba.druid.bvt.filter.wall.mysql; + +import com.alibaba.druid.wall.WallCheckResult; +import com.alibaba.druid.wall.WallProvider; +import com.alibaba.druid.wall.spi.MySqlWallProvider; +import junit.framework.TestCase; + +public class MySqlWallTest150 extends TestCase { + + public void test_false() throws Exception { + WallProvider provider = new MySqlWallProvider(); + + provider.getConfig().setSelectLimit(100); + + String sql = "select\n" + + "a.main_card_no as card_no, a.city, a.bussiness_type, 'main' as card_type,\n" + + "c.company_name as company, a.status_flag,\n" + + "a.card_balance as balance from oil_card_main a left join oil_company c on c.company_id=a.company_id\n" + + "\n" + + "union all\n" + + "\n" + + "select\n" + + "b.card_no,b.city,b.bussiness_type,'secon' as card_type,c.company_name as company,\n" + + "b.status_flag,b.card_balance as balance\n" + + "from oil_card_associate b left join oil_card_main a\n" + + "on a.main_card_no = b.main_card_no\n" + + "left join oil_company c on c.company_id=a.company_id"; + +// assertTrue( +// provider.checkValid(sql) +// ); + + WallCheckResult result = provider.check(sql); + assertEquals(0, result.getViolations().size()); + String wsql = result + .getStatementList().get(0).toString(); + + assertEquals("SELECT a.main_card_no AS card_no, a.city, a.bussiness_type, 'main' AS card_type, c.company_name AS company\n" + + "\t, a.status_flag, a.card_balance AS balance\n" + + "FROM oil_card_main a\n" + + "\tLEFT JOIN oil_company c ON c.company_id = a.company_id\n" + + "UNION ALL\n" + + "SELECT b.card_no, b.city, b.bussiness_type, 'secon' AS card_type, c.company_name AS company\n" + + "\t, b.status_flag, b.card_balance AS balance\n" + + "FROM oil_card_associate b\n" + + "\tLEFT JOIN oil_card_main a ON a.main_card_no = b.main_card_no\n" + + "\tLEFT JOIN oil_company c ON c.company_id = a.company_id\n" + + "LIMIT 100", wsql); + } +}