This is an automated email from the ASF dual-hosted git repository.

jhyde pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git

commit 97d62ac73a8f635d07b8672f1d96990855ab7d3c
Author: Nitish Kumar <[email protected]>
AuthorDate: Tue Jun 4 17:40:20 2024 +0530

    [CALCITE-6414] JDBC adapter should generate BOOLOR_AGG, BOOLAND_AGG for 
MAX, MIN on BOOLEAN values in Snowflake dialect
    
    Close apache/calcite#3812
---
 .../calcite/sql/dialect/SnowflakeSqlDialect.java   | 32 ++++++++++++++++++++++
 .../calcite/rel/rel2sql/RelToSqlConverterTest.java |  5 ++++
 2 files changed, 37 insertions(+)

diff --git 
a/core/src/main/java/org/apache/calcite/sql/dialect/SnowflakeSqlDialect.java 
b/core/src/main/java/org/apache/calcite/sql/dialect/SnowflakeSqlDialect.java
index 9b38821202..9686a9ec1b 100644
--- a/core/src/main/java/org/apache/calcite/sql/dialect/SnowflakeSqlDialect.java
+++ b/core/src/main/java/org/apache/calcite/sql/dialect/SnowflakeSqlDialect.java
@@ -17,11 +17,17 @@
 package org.apache.calcite.sql.dialect;
 
 import org.apache.calcite.avatica.util.Casing;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.sql.SqlBasicCall;
 import org.apache.calcite.sql.SqlCall;
 import org.apache.calcite.sql.SqlDialect;
+import org.apache.calcite.sql.SqlKind;
+import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlOperator;
 import org.apache.calcite.sql.SqlWriter;
 import org.apache.calcite.sql.fun.SqlLibraryOperators;
 import org.apache.calcite.sql.parser.SqlParserPos;
+import org.apache.calcite.sql.type.SqlTypeName;
 
 /**
  * A <code>SqlDialect</code> implementation for the Snowflake database.
@@ -73,6 +79,32 @@ public class SnowflakeSqlDialect extends SqlDialect {
     }
   }
 
+  @Override public SqlNode rewriteMaxMinExpr(SqlNode aggCall, RelDataType 
relDataType) {
+    return rewriteMaxMin(aggCall, relDataType);
+  }
+
+  /**
+   * Helper for rewrites of MAX/MIN.
+   * Snowflake, rewrite as
+   * BOOLOR_AGG/BOOLAND_AGG if the return type is BOOLEAN.
+   */
+  public static SqlNode rewriteMaxMin(SqlNode aggCall, RelDataType 
relDataType) {
+    // The behavior of this method depends on the argument type,
+    // and whether it is MIN/MAX
+    final SqlTypeName type = relDataType.getSqlTypeName();
+    final boolean isMax = aggCall.getKind() == SqlKind.MAX;
+    // If the type is BOOLEAN, create a new call to the correct operator
+    if (type == SqlTypeName.BOOLEAN) {
+      final SqlOperator op =
+          isMax ? SqlLibraryOperators.BOOLOR_AGG
+              : SqlLibraryOperators.BOOLAND_AGG;
+      final SqlNode operand = ((SqlBasicCall) aggCall).operand(0);
+      return op.createCall(SqlParserPos.ZERO, operand);
+    }
+    // Otherwise, just return as it arrived
+    return aggCall;
+  }
+
   @Override public boolean supportsApproxCountDistinct() {
     return true;
   }
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 1e8da43a2f..af4ff86794 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
@@ -6968,10 +6968,15 @@ class RelToSqlConverterTest {
         + "BOOL_AND(\"brand_name\" = 'a'), "
         + "MIN(\"brand_name\")\n"
         + "FROM \"foodmart\".\"product\"";
+    final String expectedSnowflake = "SELECT BOOLOR_AGG(\"brand_name\" = 'a'), 
"
+        + "BOOLAND_AGG(\"brand_name\" = 'a'), "
+        + "MIN(\"brand_name\")\n"
+        + "FROM \"foodmart\".\"product\"";
     sql(query)
       .ok(expected)
       .withBigQuery().ok(expectedBigQuery)
       .withPostgresql().ok(expectedPostgres)
+      .withSnowflake().ok(expectedSnowflake)
       .withRedshift().ok(expectedPostgres);
   }
 

Reply via email to