diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 4f99b57b7776b13994280e793527261c80862e64..c5fccae9f018f20061ad1292a536cc4b57dba95b 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -3,6 +3,7 @@ ### 缺陷修正 1. [ISSUE #334](https://github.com/dangdangdotcom/sharding-jdbc/issues/334) 解析有函数的ORDER BY会将后面的ASC, DESC解析到OrderItem的name属性中 +1. [ISSUE #335](https://github.com/dangdangdotcom/sharding-jdbc/issues/335) 支持GROUP BY + 自定义函数的SQL ## 1.5.1 diff --git a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/statement/dql/select/AbstractSelectParser.java b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/statement/dql/select/AbstractSelectParser.java index 812b482b422f320f8afb62e3418c1976e571bb05..4614d316a4ef2243ad0298152f7421cc86ce002b 100755 --- a/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/statement/dql/select/AbstractSelectParser.java +++ b/sharding-jdbc-core/src/main/java/com/dangdang/ddframe/rdb/sharding/parsing/parser/statement/dql/select/AbstractSelectParser.java @@ -140,18 +140,22 @@ public abstract class AbstractSelectParser implements SQLStatementParser { selectStatement.getItems().add(parseRowNumberSelectItem()); return; } - String literals = sqlParser.getLexer().getCurrentToken().getLiterals(); - if (Symbol.STAR.getLiterals().equals(SQLUtil.getExactlyValue(literals))) { + if (isStarSelectItem()) { selectStatement.getItems().add(parseStarSelectItem()); return; } if (isAggregationSelectItem()) { - selectStatement.getItems().add(parseAggregationSelectItem(literals)); + selectStatement.getItems().add(parseAggregationSelectItem()); return; } StringBuilder expression = new StringBuilder(); Token lastToken = null; while (!sqlParser.equalAny(DefaultKeyword.AS) && !sqlParser.equalAny(Symbol.COMMA) && !sqlParser.equalAny(DefaultKeyword.FROM) && !sqlParser.equalAny(Assist.END)) { + if (sqlParser.equalAny(Symbol.LEFT_PAREN)) { + expression.append(sqlParser.skipParentheses()); + lastToken = sqlParser.getLexer().getCurrentToken(); + continue; + } String value = sqlParser.getLexer().getCurrentToken().getLiterals(); int position = sqlParser.getLexer().getCurrentToken().getEndPosition() - value.length(); expression.append(value); @@ -180,6 +184,10 @@ public abstract class AbstractSelectParser implements SQLStatementParser { throw new UnsupportedOperationException("Cannot support special select item."); } + private boolean isStarSelectItem() { + return Symbol.STAR.getLiterals().equals(SQLUtil.getExactlyValue(sqlParser.getLexer().getCurrentToken().getLiterals())); + } + private SelectItem parseStarSelectItem() { if (!containSubquery) { containStarForOutQuery = true; @@ -190,11 +198,13 @@ public abstract class AbstractSelectParser implements SQLStatementParser { } private boolean isAggregationSelectItem() { - return sqlParser.skipIfEqual(DefaultKeyword.MAX, DefaultKeyword.MIN, DefaultKeyword.SUM, DefaultKeyword.AVG, DefaultKeyword.COUNT); + return sqlParser.equalAny(DefaultKeyword.MAX, DefaultKeyword.MIN, DefaultKeyword.SUM, DefaultKeyword.AVG, DefaultKeyword.COUNT); } - private SelectItem parseAggregationSelectItem(final String literals) { - return new AggregationSelectItem(AggregationType.valueOf(literals.toUpperCase()), sqlParser.skipParentheses(), sqlParser.parseAlias()); + private SelectItem parseAggregationSelectItem() { + AggregationType aggregationType = AggregationType.valueOf(sqlParser.getLexer().getCurrentToken().getLiterals().toUpperCase()); + sqlParser.getLexer().nextToken(); + return new AggregationSelectItem(aggregationType, sqlParser.skipParentheses(), sqlParser.parseAlias()); } private boolean hasAlias(final StringBuilder expression, final Token lastToken) { @@ -308,6 +318,9 @@ public abstract class AbstractSelectParser implements SQLStatementParser { } else if (sqlExpression instanceof SQLIdentifierExpression) { SQLIdentifierExpression sqlIdentifierExpression = (SQLIdentifierExpression) sqlExpression; orderItem = new OrderItem(SQLUtil.getExactlyValue(sqlIdentifierExpression.getName()), orderByType, getAlias(SQLUtil.getExactlyValue(sqlIdentifierExpression.getName()))); + } else if (sqlExpression instanceof SQLIgnoreExpression) { + SQLIgnoreExpression sqlIgnoreExpression = (SQLIgnoreExpression) sqlExpression; + orderItem = new OrderItem(sqlIgnoreExpression.getExpression(), orderByType, getAlias(sqlIgnoreExpression.getExpression())); } else { return; }