@@ -104,6 +104,7 @@ public abstract class AbstractSQLConfig implements SQLConfig {
104104 // 自定义原始 SQL 片段 Map<key, substring>:当 substring 为 null 时忽略;当 substring 为 "" 时整个 value 是 raw SQL;其它情况则只是 substring 这段为 raw SQL
105105 public static final Map <String , String > RAW_MAP ;
106106 // 允许调用的 SQL 函数:当 substring 为 null 时忽略;当 substring 为 "" 时整个 value 是 raw SQL;其它情况则只是 substring 这段为 raw SQL
107+ public static final Map <String , String > SQL_AGGREGATE_FUNCTION_MAP ;
107108 public static final Map <String , String > SQL_FUNCTION_MAP ;
108109
109110
@@ -242,6 +243,13 @@ public abstract class AbstractSQLConfig implements SQLConfig {
242243
243244
244245
246+ SQL_AGGREGATE_FUNCTION_MAP = new LinkedHashMap <>(); // 保证顺序,避免配置冲突等意外情况
247+ SQL_AGGREGATE_FUNCTION_MAP .put ("max" , "" );
248+ SQL_AGGREGATE_FUNCTION_MAP .put ("min" , "" );
249+ SQL_AGGREGATE_FUNCTION_MAP .put ("avg" , "" );
250+ SQL_AGGREGATE_FUNCTION_MAP .put ("count" , "" );
251+ SQL_AGGREGATE_FUNCTION_MAP .put ("sum" , "" );
252+
245253 SQL_FUNCTION_MAP = new LinkedHashMap <>(); // 保证顺序,避免配置冲突等意外情况
246254
247255 //窗口函数
@@ -761,6 +769,7 @@ public String getUserIdKey() {
761769 private int page ; //Table所在页码
762770 private int position ; //Table在[]中的位置
763771 private int query ; //JSONRequest.query
772+ private Boolean compat ; //JSONRequest.compat query total
764773 private int type ; //ObjectParser.type
765774 private int cache ;
766775 private boolean explain ;
@@ -1458,14 +1467,9 @@ public String getColumnString(boolean inSQLJoin) throws Exception {
14581467 case HEAD :
14591468 case HEADS : //StringUtil.isEmpty(column, true) || column.contains(",") 时SQL.count(column)会return "*"
14601469 if (isPrepared () && column != null ) {
1461-
14621470 List <String > raw = getRaw ();
14631471 boolean containRaw = raw != null && raw .contains (KEY_COLUMN );
1464-
1465- String origin ;
1466- String alias ;
1467- int index ;
1468-
1472+
14691473 for (String c : column ) {
14701474 if (containRaw ) {
14711475 // 由于 HashMap 对 key 做了 hash 处理,所以 get 比 containsValue 更快
@@ -1476,9 +1480,9 @@ public String getColumnString(boolean inSQLJoin) throws Exception {
14761480 }
14771481 }
14781482
1479- index = c .lastIndexOf (":" ); //StringUtil.split返回数组中,子项不会有null
1480- origin = index < 0 ? c : c .substring (0 , index );
1481- alias = index < 0 ? null : c .substring (index + 1 );
1483+ int index = c .lastIndexOf (":" ); //StringUtil.split返回数组中,子项不会有null
1484+ String origin = index < 0 ? c : c .substring (0 , index );
1485+ String alias = index < 0 ? null : c .substring (index + 1 );
14821486
14831487 if (alias != null && StringUtil .isName (alias ) == false ) {
14841488 throw new IllegalArgumentException ("HEAD请求: 字符 " + alias + " 不合法!预编译模式下 @column:value 中 value里面用 , 分割的每一项"
@@ -1499,8 +1503,41 @@ public String getColumnString(boolean inSQLJoin) throws Exception {
14991503 }
15001504 }
15011505 }
1506+
1507+ boolean onlyOne = column != null && column .size () == 1 ;
1508+ String c0 = onlyOne ? column .get (0 ) : null ;
1509+
1510+ if (onlyOne ) {
1511+ int index = c0 == null ? -1 : c0 .lastIndexOf (":" );
1512+ if (index > 0 ) {
1513+ c0 = c0 .substring (0 , index );
1514+ }
1515+
1516+ int start = c0 == null ? -1 : c0 .indexOf ("(" );
1517+ int end = start <= 0 ? -1 : c0 .lastIndexOf (")" );
1518+ if (start > 0 && end > start ) {
1519+ String fun = c0 .substring (0 , start );
1520+
1521+ // Invalid use of group function SELECT count(max(`id`)) AS count FROM `sys`.`Comment`
1522+ if (SQL_AGGREGATE_FUNCTION_MAP .containsKey (fun )) {
1523+ String group = getGroup (); // TODO 唯一 100% 兼容的可能只有 SELECT count(*) FROM (原语句) AS table
1524+ return StringUtil .isEmpty (group , true ) ? "1" : "count(DISTINCT " + group + ")" ;
1525+ }
1526+
1527+ String [] args = start == end - 1 ? null : StringUtil .split (c0 .substring (start + 1 , end ));
1528+ if (args == null || args .length <= 0 ) {
1529+ return SQL .count (c0 );
1530+ }
15021531
1503- return SQL .count (column != null && column .size () == 1 && StringUtil .isName (column .get (0 )) ? getKey (column .get (0 )) : "*" );
1532+ List <String > raw = getRaw ();
1533+ boolean containRaw = raw != null && raw .contains (KEY_COLUMN );
1534+
1535+ return SQL .count (parseColumn (c0 , containRaw ));
1536+ }
1537+ }
1538+
1539+ return SQL .count (onlyOne ? getKey (c0 ) : "*" );
1540+ // return SQL.count(onlyOne && StringUtil.isName(column.get(0)) ? getKey(column.get(0)) : "*");
15041541 case POST :
15051542 if (column == null || column .isEmpty ()) {
15061543 throw new IllegalArgumentException ("POST 请求必须在Table内设置要保存的 key:value !" );
@@ -1997,6 +2034,16 @@ public AbstractSQLConfig setQuery(int query) {
19972034 this .query = query ;
19982035 return this ;
19992036 }
2037+ @ Override
2038+ public Boolean getCompat () {
2039+ return compat ;
2040+ }
2041+ @ Override
2042+ public AbstractSQLConfig setCompat (Boolean compat ) {
2043+ this .compat = compat ;
2044+ return this ;
2045+ }
2046+
20002047 @ Override
20012048 public int getType () {
20022049 return type ;
@@ -3753,14 +3800,13 @@ private static String getConditionString(String column, String table, AbstractSQ
37533800
37543801 //根据方法不同,聚合语句不同。GROUP BY 和 HAVING 可以加在 HEAD 上, HAVING 可以加在 PUT, DELETE 上,GET 全加,POST 全都不加
37553802 String aggregation = "" ;
3756- if (RequestMethod .isGetMethod (config .getMethod (), true )){
3757- aggregation = config .getGroupString (true ) + config .getHavingString (true ) +
3758- config .getOrderString (true );
3803+ if (RequestMethod .isGetMethod (config .getMethod (), true )) {
3804+ aggregation = config .getGroupString (true ) + config .getHavingString (true ) + config .getOrderString (true );
37593805 }
3760- if (RequestMethod .isHeadMethod (config .getMethod (), true )){
3806+ if (RequestMethod .isHeadMethod (config .getMethod (), true )) { // TODO 加参数 isPagenation 判断是 GET 内分页 query:2 查总数,不用加这些条件
37613807 aggregation = config .getGroupString (true ) + config .getHavingString (true ) ;
37623808 }
3763- if (config .getMethod () == PUT || config .getMethod () == DELETE ){
3809+ if (config .getMethod () == PUT || config .getMethod () == DELETE ) {
37643810 aggregation = config .getHavingString (true ) ;
37653811 }
37663812
@@ -3825,6 +3871,8 @@ public String getJoinString() throws Exception {
38253871
38263872 // 主表不用别名 String ta;
38273873 for (Join j : joinList ) {
3874+ onGetJoinString (j );
3875+
38283876 if (j .isAppJoin ()) { // APP JOIN,只是作为一个标记,执行完主表的查询后自动执行副表的查询 User.id IN($commentIdList)
38293877 continue ;
38303878 }
@@ -4089,6 +4137,9 @@ protected void onJoinNotRelation(String sql, String quote, Join j, String jt, Li
40894137 protected void onJoinComplextRelation (String sql , String quote , Join j , String jt , List <On > onList , On on ) {
40904138 throw new UnsupportedOperationException ("JOIN 已禁用 $, ~, {}, <>, >, <, >=, <= 等复杂关联 !性能很差、需求极少,默认只允许 = 等价关联,如要取消禁用可在后端重写相关方法!" );
40914139 }
4140+
4141+ protected void onGetJoinString (Join j ) throws UnsupportedOperationException {
4142+ }
40924143 protected void onGetCrossJoinString (Join j ) throws UnsupportedOperationException {
40934144 throw new UnsupportedOperationException ("已禁用 * CROSS JOIN !性能很差、需求极少,如要取消禁用可在后端重写相关方法!" );
40944145 }
0 commit comments