Fix/grouping sets comma (#6645) chore: clean checkstyle violations in SQLServerCollateTest Trim the blank line after the class opening brace and the trailing blank lines at end-of-file so the maven-checkstyle-plugin (bound to the validate phase) stops blocking the surefire run. Pure formatting fix, no logic change. chore: import openspec scaffold (config, templates, baseline specs) Imports the openspec workflow scaffolding that lives on the sibling branches but has not yet landed on master: openspec/config.yaml — project context + per-artifact rules openspec/templates/ — proposal/spec/tasks/design templates openspec/specs// — baseline spec.md for 8 capabilities (connection-pool-core, dialect-registration, feature-gate-naming, filter-chain, monitoring-stat, sql-parser-core, test-infrastructure-core, wall-security) Sourced verbatim from the existing branches that introduced the layout; no content changes. This commit is content-only; the change-record / spec delta for the GROUPING SETS fix lives in a follow-up commit. fix: preserve comma separator before GROUPING SETS in GROUP BY ODPS / Hive / Oracle distinguish two surface forms in GROUP BY: GROUP BY a, GROUPING SETS((a, b), (a), (b), ()) -- with comma GROUP BY a GROUPING SETS((a, b), (a), (b), ()) -- no commaBefore this fix the parser collapsed both into the same AST and the output visitor unconditionally dropped the comma, so a parse + emit roundtrip silently rewrote the SQL. Three coordinated changes: SQLGroupingSetExpr gains a hasPrefixComma flag (default true to preserve the historically dominant emit shape for AST builders that did not previously distinguish the two forms). The flag participates in clone(), equals(Object) and hashCode(). SQLSelectParser.parseGroupBy tracks whether the previous loop iteration consumed a comma; when the next parsed item is a SQLGroupingSetExpr and no comma was consumed, the parser marks it hasPrefixComma=false. The reverse “HAVING … GROUP BY” loop is left untouched because it only recognises COMMA as a separator and cannot reach the no-comma branch. SQLASTOutputVisitor.visit(SQLSelectGroupByClause) emits a comma before a non-first SQLGroupingSetExpr sibling iff its hasPrefixComma flag is true; otherwise the historical newline-only formatting is kept. The fix lives in the base visitor so every dialect output visitor inheriting from it (ODPS, Hive, Oracle, MySQL, Spark, ClickHouse, SQLServer …) picks up the behaviour. Adds OdpsGroupingSetsCommaTest covering ODPS exact-string roundtrip for the comma / no-comma / grouping-sets-only forms, cross-dialect smoke tests for Hive and Oracle, and AST-level invariants (default flag, clone propagation, equals/hashCode distinguishing the flag, programmatic default emit shape). docs(openspec): record GROUPING SETS comma fix as archived change Adds the openspec change record for the GROUPING SETS comma fix and syncs the new scenarios into the sql-parser-core baseline spec: openspec/specs/sql-parser-core/spec.md + Requirement “GROUP BY GROUPING SETS Separator Preservation” with six scenarios covering parse + emit roundtrip for the comma / no-comma / grouping-sets-only forms, programmatic default emit shape, AST equality, and clone propagation. openspec/changes/archive/2026-05-12-fix-grouping-sets-comma/ proposal.md, tasks.md, verification-notes.md, .openspec.yaml and the matching ADDED-Requirements delta spec under specs/sql-parser-core/spec.md. The change is filed directly into archive/ because it ships as part of the same commit series as the implementation; the baseline already reflects the new Requirement so there is no pending delta to apply.
Fix/grouping sets comma (#6645)
Trim the blank line after the class opening brace and the trailing blank lines at end-of-file so the maven-checkstyle-plugin (bound to the validate phase) stops blocking the surefire run. Pure formatting fix, no logic change.
Imports the openspec workflow scaffolding that lives on the sibling branches but has not yet landed on master:
openspec/config.yaml — project context + per-artifact rules openspec/templates/ — proposal/spec/tasks/design templates openspec/specs// — baseline spec.md for 8 capabilities (connection-pool-core, dialect-registration, feature-gate-naming, filter-chain, monitoring-stat, sql-parser-core, test-infrastructure-core, wall-security)
Sourced verbatim from the existing branches that introduced the layout; no content changes. This commit is content-only; the change-record / spec delta for the GROUPING SETS fix lives in a follow-up commit.
ODPS / Hive / Oracle distinguish two surface forms in GROUP BY:
GROUP BY a, GROUPING SETS((a, b), (a), (b), ()) -- with comma GROUP BY a GROUPING SETS((a, b), (a), (b), ()) -- no comma
Before this fix the parser collapsed both into the same AST and the output visitor unconditionally dropped the comma, so a parse + emit roundtrip silently rewrote the SQL.
Three coordinated changes:
SQLGroupingSetExpr gains a hasPrefixComma flag (default true to preserve the historically dominant emit shape for AST builders that did not previously distinguish the two forms). The flag participates in clone(), equals(Object) and hashCode().
SQLSelectParser.parseGroupBy tracks whether the previous loop iteration consumed a comma; when the next parsed item is a SQLGroupingSetExpr and no comma was consumed, the parser marks it hasPrefixComma=false. The reverse “HAVING … GROUP BY” loop is left untouched because it only recognises COMMA as a separator and cannot reach the no-comma branch.
SQLASTOutputVisitor.visit(SQLSelectGroupByClause) emits a comma before a non-first SQLGroupingSetExpr sibling iff its hasPrefixComma flag is true; otherwise the historical newline-only formatting is kept. The fix lives in the base visitor so every dialect output visitor inheriting from it (ODPS, Hive, Oracle, MySQL, Spark, ClickHouse, SQLServer …) picks up the behaviour.
Adds OdpsGroupingSetsCommaTest covering ODPS exact-string roundtrip for the comma / no-comma / grouping-sets-only forms, cross-dialect smoke tests for Hive and Oracle, and AST-level invariants (default flag, clone propagation, equals/hashCode distinguishing the flag, programmatic default emit shape).
Adds the openspec change record for the GROUPING SETS comma fix and syncs the new scenarios into the sql-parser-core baseline spec:
openspec/specs/sql-parser-core/spec.md + Requirement “GROUP BY GROUPING SETS Separator Preservation” with six scenarios covering parse + emit roundtrip for the comma / no-comma / grouping-sets-only forms, programmatic default emit shape, AST equality, and clone propagation.
openspec/changes/archive/2026-05-12-fix-grouping-sets-comma/ proposal.md, tasks.md, verification-notes.md, .openspec.yaml and the matching ADDED-Requirements delta spec under specs/sql-parser-core/spec.md.
The change is filed directly into archive/ because it ships as part of the same commit series as the implementation; the baseline already reflects the new Requirement so there is no pending delta to apply.
English | 中文
Druid 是阿里巴巴开源的高性能数据库连接池和 SQL 解析器。它将 JDBC 连接池、SQL 解析分析、安全防护和监控统计深度整合为一体,是 Java 生态中功能最全面的数据库中间件之一。
DruidDataSource
WallFilter
StatFilter
HighAvailableDataSource
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.24</version> </dependency>
根据 Spring Boot 版本选择对应 Starter:
druid-spring-boot-starter
druid-spring-boot-3-starter
druid-spring-boot-4-starter
<!-- Spring Boot 3.x 示例 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-3-starter</artifactId> <version>1.2.24</version> </dependency>
# application.yml spring: datasource: url: jdbc:mysql://localhost:3306/mydb username: root password: password druid: initial-size: 5 max-active: 20 min-idle: 5 max-wait: 60000 # 启用 Filter filter: stat: enabled: true log-slow-sql: true slow-sql-millis: 2000 wall: enabled: true
DruidDataSource dataSource = new DruidDataSource(); dataSource.setUrl("jdbc:mysql://localhost:3306/mydb"); dataSource.setUsername("root"); dataSource.setPassword("password"); dataSource.setInitialSize(5); dataSource.setMaxActive(20); dataSource.setMinIdle(5); dataSource.init(); // 使用连接 try (Connection conn = dataSource.getConnection()) { // 执行 SQL }
// 解析 SQL String sql = "SELECT id, name FROM users WHERE age > 18 ORDER BY name"; List<SQLStatement> stmts = SQLUtils.parseStatements(sql, DbType.mysql); // 格式化 SQL String formatted = SQLUtils.format(sql, DbType.mysql); // 获取表信息 SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(DbType.mysql); stmts.get(0).accept(visitor); System.out.println("Tables: " + visitor.getTables()); System.out.println("Columns: " + visitor.getColumns());
druid/ ├── core/ # 核心库(连接池、SQL 解析、安全、监控) ├── druid-spring-boot-starter/ # Spring Boot 2.x 自动配置 ├── druid-spring-boot-3-starter/ # Spring Boot 3.x 自动配置 ├── druid-spring-boot-4-starter/ # Spring Boot 4.x 自动配置 ├── druid-wrapper/ # 包装工具 ├── druid-admin/ # 集群监控管理端 └── doc/ # 文档
Druid SQL 解析器支持 30 种数据库方言,每种方言都提供完整的 Lexer、Parser、AST 和 Visitor 实现:
git clone https://github.com/alibaba/druid.git cd druid mvn clean install
要求: Java 8+ JDK,Apache Maven 3.6+
欢迎参与 Druid 项目!请阅读 贡献指南 了解如何参与开发。
请勿通过公开 Issue 报告安全漏洞。详见 安全策略。
Druid 基于 Apache License 2.0 开源。
Alibaba Druid
English | 中文
Druid 是阿里巴巴开源的高性能数据库连接池和 SQL 解析器。它将 JDBC 连接池、SQL 解析分析、安全防护和监控统计深度整合为一体,是 Java 生态中功能最全面的数据库中间件之一。
核心特性
DruidDataSource,支持物理连接预热、PSCache、KeepAlive 等高级特性WallFilterSQL 安全防护,可拦截 SQL 注入、危险操作等StatFilter实时采集 SQL 执行统计、连接池状态,提供 Web 监控页面HighAvailableDataSource支持多数据源负载均衡、健康检查和故障切换快速开始
Maven 依赖
Spring Boot 项目(推荐)
根据 Spring Boot 版本选择对应 Starter:
druid-spring-boot-starterdruid-spring-boot-3-starterdruid-spring-boot-4-starter直接使用 DruidDataSource
SQL 解析器
项目模块
SQL 方言支持
Druid SQL 解析器支持 30 种数据库方言,每种方言都提供完整的 Lexer、Parser、AST 和 Visitor 实现:
文档
从源码构建
要求: Java 8+ JDK,Apache Maven 3.6+
贡献
欢迎参与 Druid 项目!请阅读 贡献指南 了解如何参与开发。
安全漏洞
请勿通过公开 Issue 报告安全漏洞。详见 安全策略。
相关阿里云产品
License
Druid 基于 Apache License 2.0 开源。