You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by al...@apache.org on 2021/07/02 21:18:06 UTC

[arrow-datafusion] branch master updated: Add support for leading field in interval (#647)

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

alamb pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow-datafusion.git


The following commit(s) were added to refs/heads/master by this push:
     new 8d8558b  Add support for leading field in interval (#647)
8d8558b is described below

commit 8d8558bb50786aa37b544722ee5511fb7e5cbd50
Author: Daniƫl Heres <da...@gmail.com>
AuthorDate: Fri Jul 2 23:17:58 2021 +0200

    Add support for leading field in interval (#647)
    
    * Add support for leading field in interval
    
    * Naming
    
    * Fix clippy, tests
---
 datafusion/src/sql/planner.rs | 23 ++++++++++++-----------
 datafusion/tests/sql.rs       | 17 +++++++++++++++++
 2 files changed, 29 insertions(+), 11 deletions(-)

diff --git a/datafusion/src/sql/planner.rs b/datafusion/src/sql/planner.rs
index b86dc0f..213ae89 100644
--- a/datafusion/src/sql/planner.rs
+++ b/datafusion/src/sql/planner.rs
@@ -1264,13 +1264,6 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
         last_field: &Option<DateTimeField>,
         fractional_seconds_precision: &Option<u64>,
     ) -> Result<Expr> {
-        if leading_field.is_some() {
-            return Err(DataFusionError::NotImplemented(format!(
-                "Unsupported Interval Expression with leading_field {:?}",
-                leading_field
-            )));
-        }
-
         if leading_precision.is_some() {
             return Err(DataFusionError::NotImplemented(format!(
                 "Unsupported Interval Expression with leading_precision {:?}",
@@ -1367,10 +1360,18 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
                 break;
             }
 
-            let (diff_month, diff_days, diff_millis) = calculate_from_part(
-                interval_period_str.unwrap(),
-                parts.next().unwrap_or("second"),
-            )?;
+            let leading_field = leading_field
+                .as_ref()
+                .map(|dt| dt.to_string())
+                .unwrap_or_else(|| "second".to_string());
+
+            let unit = parts
+                .next()
+                .map(|part| part.to_string())
+                .unwrap_or(leading_field);
+
+            let (diff_month, diff_days, diff_millis) =
+                calculate_from_part(interval_period_str.unwrap(), &unit)?;
 
             result_month += diff_month as i64;
 
diff --git a/datafusion/tests/sql.rs b/datafusion/tests/sql.rs
index 5cb5529..82c12ce 100644
--- a/datafusion/tests/sql.rs
+++ b/datafusion/tests/sql.rs
@@ -3300,6 +3300,11 @@ async fn test_interval_expressions() -> Result<()> {
         "interval '5 day'",
         "0 years 0 mons 5 days 0 hours 0 mins 0.00 secs"
     );
+    // Hour is ignored, this matches PostgreSQL
+    test_expression!(
+        "interval '5 day' hour",
+        "0 years 0 mons 5 days 0 hours 0 mins 0.00 secs"
+    );
     test_expression!(
         "interval '5 day 4 hours 3 minutes 2 seconds 100 milliseconds'",
         "0 years 0 mons 5 days 4 hours 3 mins 2.100 secs"
@@ -3309,10 +3314,18 @@ async fn test_interval_expressions() -> Result<()> {
         "0 years 0 mons 15 days 0 hours 0 mins 0.00 secs"
     );
     test_expression!(
+        "interval '0.5' month",
+        "0 years 0 mons 15 days 0 hours 0 mins 0.00 secs"
+    );
+    test_expression!(
         "interval '1 month'",
         "0 years 1 mons 0 days 0 hours 0 mins 0.00 secs"
     );
     test_expression!(
+        "interval '1' MONTH",
+        "0 years 1 mons 0 days 0 hours 0 mins 0.00 secs"
+    );
+    test_expression!(
         "interval '5 month'",
         "0 years 5 mons 0 days 0 hours 0 mins 0.00 secs"
     );
@@ -3332,6 +3345,10 @@ async fn test_interval_expressions() -> Result<()> {
         "interval '2 year'",
         "2 years 0 mons 0 days 0 hours 0 mins 0.00 secs"
     );
+    test_expression!(
+        "interval '2' year",
+        "2 years 0 mons 0 days 0 hours 0 mins 0.00 secs"
+    );
     Ok(())
 }