This is an automated email from the ASF dual-hosted git repository.
mihaibudiu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/main by this push:
new a5b9dd2a6a [CALCITE-7679] RelToSqlConverter generates GROUP BY
literals for dialects that do not support them when the constant is hidden by
nested Projects
a5b9dd2a6a is described below
commit a5b9dd2a6a078ec29b52dbbe4e26b05133cc006e
Author: Dongsheng He <[email protected]>
AuthorDate: Tue Jul 28 23:01:42 2026 +0800
[CALCITE-7679] RelToSqlConverter generates GROUP BY literals for dialects
that do not support them when the constant is hidden by nested Projects
---
.../apache/calcite/rel/rel2sql/SqlImplementor.java | 33 ++++++++++++++
.../calcite/rel/rel2sql/RelToSqlConverterTest.java | 50 ++++++++++++++++++++++
2 files changed, 83 insertions(+)
diff --git
a/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java
b/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java
index b65a797f14..c2804db09e 100644
--- a/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java
+++ b/core/src/main/java/org/apache/calcite/rel/rel2sql/SqlImplementor.java
@@ -2261,8 +2261,41 @@ && hasSortByOrdinal(node)) {
if (groupKeysContainOver(agg)) {
return true;
}
+
+ if (!dialect.supportsGroupByLiteral()
+ && hasGroupByLiteral(agg)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns whether any grouping key of {@code aggregate} is represented by
+ * a literal expression in this result's {@code SELECT} list.
+ */
+ private boolean hasGroupByLiteral(
+ @UnknownInitialization Result this, Aggregate aggregate) {
+ if (!(node instanceof SqlSelect)) {
+ return false;
}
+ final SqlNodeList selectList = ((SqlSelect) node).getSelectList();
+ if (selectList.equals(SqlNodeList.SINGLETON_STAR)) {
+ return false;
+ }
+
+ for (int groupKey : aggregate.getGroupSet()) {
+ if (groupKey >= selectList.size()) {
+ return false;
+ }
+ final SqlNode expression = SqlUtil.stripAs(selectList.get(groupKey));
+ // A literal wrapped in a CAST is also considered a literal.
+ if (SqlUtil.isLiteral(expression, true)) {
+ return true;
+ }
+ }
return false;
}
diff --git
a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
index 01f1578936..ad43cd0591 100644
---
a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
+++
b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
@@ -370,6 +370,56 @@ private static String toSql(RelNode root, SqlDialect
dialect,
.withInformix().ok(expectedInformix);
}
+ /** Test case for
+ * <a
href="https://issues.apache.org/jira/browse/CALCITE-7679">[CALCITE-7679]
+ * RelToSqlConverter generates GROUP BY literals for dialects that do not
+ * support them when the constant is hidden by nested Projects</a>. */
+ @Test void testGroupByLiteralWithNestedProjects() {
+ final String query = "SELECT \"id\"\n"
+ + "FROM (\n"
+ + " SELECT \"id\"\n"
+ + " FROM (\n"
+ + " SELECT NULL AS \"id\"\n"
+ + " FROM \"employee\"\n"
+ + " ) AS \"t1\"\n"
+ + ") AS \"t2\"\n"
+ + "GROUP BY \"id\"";
+ final String expectedPostgresql = "SELECT \"id\"\n"
+ + "FROM (SELECT NULL AS \"id\"\n"
+ + "FROM \"foodmart\".\"employee\") AS \"t0\"\n"
+ + "GROUP BY \"id\"";
+ sql(query)
+ // Disable RelBuilder's eager Project merging to retain the nested
+ // Projects that reproduce the constant GROUP BY conversion issue.
+ .withConfig(c -> c.withRelBuilderConfigTransform(b -> b.withBloat(-1)))
+ .withPostgresql().ok(expectedPostgresql);
+ }
+
+ /** Test case for
+ * <a
href="https://issues.apache.org/jira/browse/CALCITE-7679">[CALCITE-7679]
+ * RelToSqlConverter generates GROUP BY literals for dialects that do not
+ * support them when the constant is hidden by nested Projects</a>. */
+ @Test void testGroupByLiteralWithReorderedNestedProjects() {
+ final String query = "SELECT \"id\", \"employee_id\"\n"
+ + "FROM (\n"
+ + " SELECT \"id\", \"employee_id\"\n"
+ + " FROM (\n"
+ + " SELECT \"employee_id\", NULL AS \"id\"\n"
+ + " FROM \"employee\"\n"
+ + " ) AS \"t1\"\n"
+ + ") AS \"t2\"\n"
+ + "GROUP BY \"id\", \"employee_id\"";
+ final String expectedPostgresql = "SELECT \"id\", \"employee_id\"\n"
+ + "FROM (SELECT NULL AS \"id\", \"employee_id\"\n"
+ + "FROM \"foodmart\".\"employee\") AS \"t0\"\n"
+ + "GROUP BY \"id\", \"employee_id\"";
+ sql(query)
+ // Disable RelBuilder's eager Project merging to retain the nested
+ // Projects that reproduce the constant GROUP BY conversion issue.
+ .withConfig(c -> c.withRelBuilderConfigTransform(b -> b.withBloat(-1)))
+ .withPostgresql().ok(expectedPostgresql);
+ }
+
/** Test case for <a
href="https://issues.apache.org/jira/browse/CALCITE-6910">[CALCITE-6910]
* RelToSql does not handle ASOF joins</a>. */
@Test void testAsofJoin() {