Skip to content

Commit 4257a40

Browse files
authored
Merge pull request #119 from jumpserver/dev
merge: v4.10.5-lts
2 parents 2598866 + ec0ce3a commit 4257a40

File tree

3 files changed

+37
-24
lines changed

3 files changed

+37
-24
lines changed

backend/framework/src/main/java/org/jumpserver/chen/framework/datasource/base/BaseSQLActuator.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import com.alibaba.druid.DbType;
44
import com.alibaba.druid.pool.DruidPooledConnection;
5-
import com.alibaba.druid.sql.PagerUtils;
65
import com.alibaba.druid.sql.SQLUtils;
76
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
87
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
@@ -225,7 +224,7 @@ public int count(SQLExecutePlan plan) throws SQLException {
225224
if (limit > 0) {
226225
return -1;
227226
}
228-
var countSQL = PagerUtils.count(plan.getSourceSQL(), plan.getDruidDbType());
227+
var countSQL = PageUtils.count(plan.getSourceSQL(), plan.getDruidDbType());
229228
try (Statement stmt = plan.createStatement()) {
230229
var resultSet = stmt.executeQuery(countSQL);
231230
if (resultSet.next()) {

backend/framework/src/main/java/org/jumpserver/chen/framework/utils/PageUtils.java

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -429,46 +429,59 @@ private static boolean limitMySqlQueryBlock(SQLSelectQueryBlock queryBlock, DbTy
429429
}
430430

431431
private static String count(SQLSelect select, DbType dbType) {
432+
// 去除 ORDER BY
432433
if (select.getOrderBy() != null) {
433-
select.setOrderBy((SQLOrderBy) null);
434+
select.setOrderBy(null);
434435
}
435436

436437
SQLSelectQuery query = select.getQuery();
437-
clearOrderBy(query);
438+
clearOrderBy(query); // 自定义的清理嵌套子查询中的 ORDER BY 的方法
439+
438440
if (query instanceof SQLSelectQueryBlock) {
439-
SQLSelectItem countItem = createCountItem(dbType);
440441
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock) query;
441442
List<SQLSelectItem> selectList = queryBlock.getSelectList();
443+
int distinctOption = queryBlock.getDistionOption();
444+
445+
// 情况 1: 存在 GROUP BY,需用子查询
442446
if (queryBlock.getGroupBy() != null && queryBlock.getGroupBy().getItems().size() > 0) {
443-
if (queryBlock.getSelectList().size() == 1 && ((SQLSelectItem) queryBlock.getSelectList().get(0)).getExpr() instanceof SQLAllColumnExpr) {
444-
queryBlock.getSelectList().clear();
445-
queryBlock.getSelectList().add(new SQLSelectItem(new SQLIntegerExpr(1)));
447+
if (selectList.size() == 1 && selectList.get(0).getExpr() instanceof SQLAllColumnExpr) {
448+
selectList.clear();
449+
selectList.add(new SQLSelectItem(new SQLIntegerExpr(1)));
446450
}
447-
448451
return createCountUseSubQuery(select, dbType);
449-
} else {
450-
int option = queryBlock.getDistionOption();
451-
if (option == 2 && selectList.size() >= 1) {
452-
SQLAggregateExpr countExpr = new SQLAggregateExpr("COUNT", SQLAggregateOption.DISTINCT);
452+
}
453453

454-
for (int i = 0; i < selectList.size(); ++i) {
455-
countExpr.addArgument(((SQLSelectItem) selectList.get(i)).getExpr());
454+
// 情况 2: DISTINCT 情况下,Oracle 特别处理
455+
if (distinctOption == SQLSetQuantifier.DISTINCT) {
456+
if (dbType == DbType.oracle && (
457+
selectList.size() > 1 ||
458+
(selectList.size() == 1 && selectList.get(0).getExpr() instanceof SQLAllColumnExpr)
459+
)) {
460+
// SELECT DISTINCT * 或多字段,Oracle 不支持直接 count(distinct ...)
461+
return createCountUseSubQuery(select, dbType);
462+
} else {
463+
// 只有一个字段,Oracle 支持 count(distinct col)
464+
SQLAggregateExpr countExpr = new SQLAggregateExpr("COUNT", SQLAggregateOption.DISTINCT);
465+
for (SQLSelectItem item : selectList) {
466+
countExpr.addArgument(item.getExpr());
456467
}
457-
458468
selectList.clear();
459-
queryBlock.setDistionOption(0);
469+
queryBlock.setDistionOption(0); // 去除 DISTINCT
460470
queryBlock.addSelectItem(countExpr);
461-
} else {
462-
selectList.clear();
463-
selectList.add(countItem);
471+
return SQLUtils.toSQLString(select, dbType);
464472
}
465-
466-
return SQLUtils.toSQLString(select, dbType);
467473
}
474+
475+
// 情况 3: 非 DISTINCT,无 GROUP BY,直接 count(*)
476+
selectList.clear();
477+
selectList.add(createCountItem(dbType));
478+
return SQLUtils.toSQLString(select, dbType);
479+
468480
} else if (query instanceof SQLUnionQuery) {
481+
// UNION 情况统一使用子查询
469482
return createCountUseSubQuery(select, dbType);
470483
} else {
471-
throw new IllegalStateException();
484+
throw new IllegalStateException("不支持的 SQL 查询类型: " + query.getClass().getName());
472485
}
473486
}
474487

backend/modules/src/main/java/org.jumpserver.chen.modules/mysql/MysqlConnectionManager.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ private void setTimeZone(Connection conn) throws SQLException {
5858
ZonedDateTime now = ZonedDateTime.now(zoneId);
5959
ZoneOffset offset = now.getOffset();
6060

61-
String offsetStr = offset.toString();
61+
String offsetStr = offset.equals(ZoneOffset.UTC) ? "+00:00" : offset.toString();
62+
6263

6364
try (Statement stmt = conn.createStatement()) {
6465
stmt.execute("SET time_zone = '" + offsetStr + "'");

0 commit comments

Comments
 (0)