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() {

Reply via email to