You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jb...@apache.org on 2022/11/29 15:26:44 UTC

[calcite] 02/02: [CALCITE-5217] Improve support for INTERVAL qualifier for Firebolt

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

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

commit 35c879044c3a1178760009fae0dd583e79856371
Author: Aymeric <ay...@firebolt.io>
AuthorDate: Wed Jul 27 17:04:23 2022 +0100

    [CALCITE-5217] Improve support for INTERVAL qualifier for Firebolt
---
 .../calcite/sql/dialect/FireboltSqlDialect.java    | 44 ++++++++++++++++++++--
 .../calcite/rel/rel2sql/RelToSqlConverterTest.java | 22 ++++++++---
 2 files changed, 58 insertions(+), 8 deletions(-)

diff --git a/core/src/main/java/org/apache/calcite/sql/dialect/FireboltSqlDialect.java b/core/src/main/java/org/apache/calcite/sql/dialect/FireboltSqlDialect.java
index d76e902a27..0f005bd307 100644
--- a/core/src/main/java/org/apache/calcite/sql/dialect/FireboltSqlDialect.java
+++ b/core/src/main/java/org/apache/calcite/sql/dialect/FireboltSqlDialect.java
@@ -16,14 +16,17 @@
  */
 package org.apache.calcite.sql.dialect;
 
+import org.apache.calcite.avatica.util.TimeUnit;
 import org.apache.calcite.avatica.util.TimeUnitRange;
 import org.apache.calcite.config.NullCollation;
 import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rel.type.RelDataTypeSystem;
 import org.apache.calcite.sql.SqlAlienSystemTypeNameSpec;
 import org.apache.calcite.sql.SqlCall;
 import org.apache.calcite.sql.SqlDataTypeSpec;
 import org.apache.calcite.sql.SqlDialect;
 import org.apache.calcite.sql.SqlIntervalLiteral;
+import org.apache.calcite.sql.SqlIntervalQualifier;
 import org.apache.calcite.sql.SqlKind;
 import org.apache.calcite.sql.SqlLiteral;
 import org.apache.calcite.sql.SqlNode;
@@ -202,17 +205,52 @@ public class FireboltSqlDialect extends SqlDialect {
     }
   }
 
+  /** Firebolt interval syntax: sign INTERVAL int64 time_unit. */
   @Override public void unparseSqlIntervalLiteral(SqlWriter writer,
       SqlIntervalLiteral literal, int leftPrec, int rightPrec) {
     SqlIntervalLiteral.IntervalValue interval =
         literal.getValueAs(SqlIntervalLiteral.IntervalValue.class);
     writer.keyword("INTERVAL");
     writer.print("'");
-    if (interval.getSign() == -1) {
-      writer.print("-");
+    try {
+      Long.parseLong(interval.getIntervalLiteral());
+    } catch (NumberFormatException e) {
+      throw new RuntimeException("Only INT64 is supported as the interval value for Firebolt.");
     }
     writer.literal(interval.getIntervalLiteral());
-    writer.print(interval.getIntervalQualifier().toString());
+    unparseSqlIntervalQualifier(writer, interval.getIntervalQualifier(),
+        RelDataTypeSystem.DEFAULT);
     writer.print("'");
   }
+
+  @Override public void unparseSqlIntervalQualifier(
+      SqlWriter writer, SqlIntervalQualifier qualifier, RelDataTypeSystem typeSystem) {
+    final String start = validate(qualifier.timeUnitRange.startUnit).name();
+    if (qualifier.timeUnitRange.endUnit == null) {
+      writer.keyword(start);
+    } else {
+      throw new RuntimeException("Range time unit is not supported for Firebolt.");
+    }
+  }
+
+  private static TimeUnit validate(TimeUnit timeUnit) {
+    switch (timeUnit) {
+    case MICROSECOND:
+    case MILLISECOND:
+    case SECOND:
+    case MINUTE:
+    case HOUR:
+    case DAY:
+    case WEEK:
+    case MONTH:
+    case YEAR:
+    case DECADE:
+    case CENTURY:
+    case MILLENNIUM:
+      return timeUnit;
+    default:
+      throw new RuntimeException("Time unit " + timeUnit + " is not supported for Firebolt.");
+    }
+  }
+
 }
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 05ef6e03c4..0cbda44c6b 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
@@ -4005,15 +4005,27 @@ class RelToSqlConverterTest {
   }
 
   @Test void testUnparseSqlIntervalQualifierFirebolt() {
-    final String sql = "select  * from \"employee\" where  \"hire_date\" + "
-        + "INTERVAL '10' HOUR > TIMESTAMP '2005-10-17 00:00:00' ";
+    final String sql0 = "select  * from \"employee\" where  \"hire_date\" - "
+        + "INTERVAL '19800' SECOND(5) > TIMESTAMP '2005-10-17 00:00:00' ";
+    final String expect0 = "SELECT *\n"
+        + "FROM \"foodmart\".\"employee\"\n"
+        + "WHERE (\"hire_date\" - INTERVAL '19800 SECOND ')"
+        + " > TIMESTAMP '2005-10-17 00:00:00'";
+    sql(sql0).withFirebolt().ok(expect0);
 
-    final String expect = "SELECT *\n"
+    final String sql1 = "select  * from \"employee\" where  \"hire_date\" + "
+        + "INTERVAL '10' HOUR > TIMESTAMP '2005-10-17 00:00:00' ";
+    final String expect1 = "SELECT *\n"
         + "FROM \"foodmart\".\"employee\"\n"
-        + "WHERE (\"hire_date\" + INTERVAL '10 HOUR')"
+        + "WHERE (\"hire_date\" + INTERVAL '10 HOUR ')"
         + " > TIMESTAMP '2005-10-17 00:00:00'";
-    sql(sql).withFirebolt().ok(expect);
+    sql(sql1).withFirebolt().ok(expect1);
+
+    final String sql2 = "select  * from \"employee\" where  \"hire_date\" + "
+        + "INTERVAL '1 2:34:56.78' DAY TO SECOND > TIMESTAMP '2005-10-17 00:00:00' ";
+    sql(sql2).withFirebolt().throws_("Only INT64 is supported as the interval value for Firebolt.");
   }
+
   @Test void testFloorMysqlWeek() {
     String query = "SELECT floor(\"hire_date\" TO WEEK) FROM \"employee\"";
     String expected = "SELECT STR_TO_DATE(DATE_FORMAT(`hire_date` , '%x%v-1'), '%x%v-%w')\n"