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"