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

xiong 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 24cc46b191 [CALCITE-7021] Support parse 'CAST('1' AS INTERVAL)'
24cc46b191 is described below

commit 24cc46b191299ca3ca2e341ea81dd097bb8ed584
Author: Juntao Zhang <[email protected]>
AuthorDate: Tue May 20 10:31:31 2025 +0800

    [CALCITE-7021] Support parse 'CAST('1' AS INTERVAL)'
---
 babel/src/main/codegen/config.fmpp                  |  1 +
 .../org/apache/calcite/test/BabelParserTest.java    |  8 ++++++++
 babel/src/test/resources/sql/postgresql.iq          | 21 +++++++++++++++++++++
 core/src/main/codegen/default_config.fmpp           |  1 +
 core/src/main/codegen/templates/Parser.jj           | 18 ++++++++++++++++++
 .../apache/calcite/sql/parser/SqlParserTest.java    |  2 ++
 6 files changed, 51 insertions(+)

diff --git a/babel/src/main/codegen/config.fmpp 
b/babel/src/main/codegen/config.fmpp
index 981768ba9d..c41f28bd71 100644
--- a/babel/src/main/codegen/config.fmpp
+++ b/babel/src/main/codegen/config.fmpp
@@ -616,6 +616,7 @@ data: {
     setOptionParserMethod: "PostgresSqlSetOption"
     includePosixOperators: true
     includeParsingStringLiteralAsArrayLiteral: true
+    includeIntervalWithoutQualifier: true
   }
 }
 
diff --git a/babel/src/test/java/org/apache/calcite/test/BabelParserTest.java 
b/babel/src/test/java/org/apache/calcite/test/BabelParserTest.java
index 11fa5489be..a0fb721aef 100644
--- a/babel/src/test/java/org/apache/calcite/test/BabelParserTest.java
+++ b/babel/src/test/java/org/apache/calcite/test/BabelParserTest.java
@@ -52,6 +52,14 @@ class BabelParserTest extends SqlParserTest {
         .withConfig(c -> c.withParserFactory(SqlBabelParserImpl.FACTORY));
   }
 
+  /** Tests that the Babel parser correctly parses a CAST to INTERVAL type
+   * in PostgreSQL dialect. */
+  @Test void testCastToInterval() {
+    SqlParserFixture postgreF = 
fixture().withDialect(PostgresqlSqlDialect.DEFAULT);
+    postgreF.sql("select cast(x as interval)")
+        .ok("SELECT CAST(\"x\" AS INTERVAL SECOND)");
+  }
+
   @Test void testReservedWords() {
     assertThat(isReserved("escape"), is(false));
   }
diff --git a/babel/src/test/resources/sql/postgresql.iq 
b/babel/src/test/resources/sql/postgresql.iq
index bc1116af2b..ef9edb7b53 100644
--- a/babel/src/test/resources/sql/postgresql.iq
+++ b/babel/src/test/resources/sql/postgresql.iq
@@ -18,6 +18,27 @@
 !use scott-postgresql
 !set outputformat csv
 
+# Test CAST INTERVAL
+select CAST('3723' AS INTERVAL HOUR TO SECOND);
+EXPR$0
++1:02:03.000000
+!ok
+
+select CAST('3721' AS INTERVAL SECOND);
+EXPR$0
++3721.000000
+!ok
+
+select CAST('2' AS INTERVAL);
+EXPR$0
++2.000000
+!ok
+
+select CAST('-3723' AS INTERVAL);
+EXPR$0
+-3723.000000
+!ok
+
 # Test string and array comparison
 select array[0,1,2] = '{0,1,2}';
 EXPR$0
diff --git a/core/src/main/codegen/default_config.fmpp 
b/core/src/main/codegen/default_config.fmpp
index f3c048bd5b..a2547273cb 100644
--- a/core/src/main/codegen/default_config.fmpp
+++ b/core/src/main/codegen/default_config.fmpp
@@ -459,4 +459,5 @@ parser: {
   includeBraces: true
   includeAdditionalDeclarations: false
   includeParsingStringLiteralAsArrayLiteral: false
+  includeIntervalWithoutQualifier: false
 }
diff --git a/core/src/main/codegen/templates/Parser.jj 
b/core/src/main/codegen/templates/Parser.jj
index fa7593c194..ae367d549a 100644
--- a/core/src/main/codegen/templates/Parser.jj
+++ b/core/src/main/codegen/templates/Parser.jj
@@ -5218,6 +5218,19 @@ TimeUnit Second() :
     <SECONDS> { return warn(TimeUnit.SECOND); }
 }
 
+SqlIntervalQualifier IntervalWithoutQualifier() :
+{
+    final Span s;
+    int secondFracPrec = RelDataType.PRECISION_NOT_SPECIFIED;
+}
+{
+    {
+        s = span();
+        return new SqlIntervalQualifier(TimeUnit.SECOND, -1, null, 
secondFracPrec,
+            s.end(this));
+    }
+}
+
 SqlIntervalQualifier IntervalQualifier() :
 {
     final Span s;
@@ -6282,7 +6295,12 @@ SqlNode BuiltinFunctionCall() :
         (
             dt = DataType() { args.add(dt); }
         |
+            LOOKAHEAD(2)
             <INTERVAL> e = IntervalQualifier() { args.add(e); }
+<#if 
(parser.includeIntervalWithoutQualifier!default.parser.includeIntervalWithoutQualifier)
 >
+        |
+            <INTERVAL> e = IntervalWithoutQualifier() { args.add(e); }
+</#if>
         )
         [ <FORMAT> format = StringLiteral() { args.add(format); } ]
         <RPAREN> {
diff --git 
a/testkit/src/main/java/org/apache/calcite/sql/parser/SqlParserTest.java 
b/testkit/src/main/java/org/apache/calcite/sql/parser/SqlParserTest.java
index 8ef2c7601e..07dc89179e 100644
--- a/testkit/src/main/java/org/apache/calcite/sql/parser/SqlParserTest.java
+++ b/testkit/src/main/java/org/apache/calcite/sql/parser/SqlParserTest.java
@@ -7250,6 +7250,8 @@ private static Consumer<List<? extends Throwable>> 
checkWarnings(
         .ok("CAST(`X` AS INTERVAL MINUTE TO SECOND)");
     expr("cast(interval '3-2' year to month as CHAR(5))")
         .ok("CAST(INTERVAL '3-2' YEAR TO MONTH AS CHAR(5))");
+    expr("cast(x as ^interval^)")
+        .fails("(?s)Encountered \"interval \\)\".*");
   }
 
   @Test void testCastToVarchar() {

Reply via email to