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

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


The following commit(s) were added to refs/heads/main by this push:
     new e7850d1e1c fix: disallow interval - timestamp (#7086)
e7850d1e1c is described below

commit e7850d1e1c6a8d4d6a82448b67aedbc6455b8cd9
Author: jakevin <[email protected]>
AuthorDate: Wed Jul 26 00:50:26 2023 +0800

    fix: disallow interval - timestamp (#7086)
---
 .../core/tests/sqllogictests/test_files/insert.slt |  2 +-
 .../tests/sqllogictests/test_files/interval.slt    | 32 ++++------------------
 .../sqllogictests/test_files/type_coercion.slt     |  8 ++----
 datafusion/expr/src/type_coercion/binary.rs        | 19 +++++++------
 4 files changed, 20 insertions(+), 41 deletions(-)

diff --git a/datafusion/core/tests/sqllogictests/test_files/insert.slt 
b/datafusion/core/tests/sqllogictests/test_files/insert.slt
index faa519834c..9f4122ac5b 100644
--- a/datafusion/core/tests/sqllogictests/test_files/insert.slt
+++ b/datafusion/core/tests/sqllogictests/test_files/insert.slt
@@ -299,4 +299,4 @@ select * from table_without_values;
 2 NULL
 
 statement ok
-drop table table_without_values;
\ No newline at end of file
+drop table table_without_values;
diff --git a/datafusion/core/tests/sqllogictests/test_files/interval.slt 
b/datafusion/core/tests/sqllogictests/test_files/interval.slt
index 1016cb155e..043f63958d 100644
--- a/datafusion/core/tests/sqllogictests/test_files/interval.slt
+++ b/datafusion/core/tests/sqllogictests/test_files/interval.slt
@@ -430,15 +430,11 @@ select '1 month'::interval + 
'1980-01-01T12:00:00'::timestamp;
 ----
 1980-02-01T12:00:00
 
-query D
+query error DataFusion error: Error during planning: Cannot coerce arithmetic 
expression Interval\(MonthDayNano\) \- Date32 to valid types
 select '1 month'::interval - '1980-01-01'::date;
-----
-1979-12-01
 
-query P
+query error DataFusion error: Error during planning: Cannot coerce arithmetic 
expression Interval\(MonthDayNano\) \- Timestamp\(Nanosecond, None\) to valid 
types
 select '1 month'::interval - '1980-01-01T12:00:00'::timestamp;
-----
-1979-12-01T12:00:00
 
 # interval (array) + date / timestamp (array)
 query D
@@ -456,19 +452,11 @@ select i + ts from t;
 2000-02-01T00:01:00
 
 # expected error interval (array) - date / timestamp (array)
-query D
+query error DataFusion error: Error during planning: Cannot coerce arithmetic 
expression Interval\(MonthDayNano\) \- Date32 to valid types
 select i - d from t;
-----
-1979-12-01
-1990-09-30
-1980-01-02
 
-query P
+query error DataFusion error: Error during planning: Cannot coerce arithmetic 
expression Interval\(MonthDayNano\) \- Timestamp\(Nanosecond, None\) to valid 
types
 select i - ts from t;
-----
-1999-12-01T00:00:00
-1999-12-31T12:11:10
-2000-01-31T23:59:00
 
 
 # interval (scalar) + date / timestamp (array)
@@ -487,19 +475,11 @@ select '1 month'::interval + ts from t;
 2000-03-01T00:00:00
 
 # expected error interval (scalar) - date / timestamp (array)
-query D
+query error DataFusion error: Error during planning: Cannot coerce arithmetic 
expression Interval\(MonthDayNano\) \- Date32 to valid types
 select '1 month'::interval - d from t;
-----
-1979-12-01
-1990-09-01
-1979-12-02
 
-query P
+query error DataFusion error: Error during planning: Cannot coerce arithmetic 
expression Interval\(MonthDayNano\) \- Timestamp\(Nanosecond, None\) to valid 
types
 select '1 month'::interval - ts from t;
-----
-1999-12-01T00:00:00
-1999-12-01T12:11:10
-2000-01-01T00:00:00
 
 # interval + date
 query D
diff --git a/datafusion/core/tests/sqllogictests/test_files/type_coercion.slt 
b/datafusion/core/tests/sqllogictests/test_files/type_coercion.slt
index 8b329df0c1..aa1e6826ec 100644
--- a/datafusion/core/tests/sqllogictests/test_files/type_coercion.slt
+++ b/datafusion/core/tests/sqllogictests/test_files/type_coercion.slt
@@ -43,13 +43,9 @@ SELECT '2023-05-01 12:30:00'::timestamp - interval '1 month';
 2023-04-01T12:30:00
 
 # interval - date
-query D
+query error DataFusion error: Error during planning: Cannot coerce arithmetic 
expression Interval\(MonthDayNano\) \- Date32 to valid types
 select interval '1 month' - '2023-05-01'::date;
-----
-2023-04-01
 
 # interval - timestamp
-query P
+query error DataFusion error: Error during planning: Cannot coerce arithmetic 
expression Interval\(MonthDayNano\) \- Timestamp\(Nanosecond, None\) to valid 
types
 SELECT interval '1 month' - '2023-05-01 12:30:00'::timestamp;
-----
-2023-04-01T12:30:00
diff --git a/datafusion/expr/src/type_coercion/binary.rs 
b/datafusion/expr/src/type_coercion/binary.rs
index b6392e2a6b..56a5664638 100644
--- a/datafusion/expr/src/type_coercion/binary.rs
+++ b/datafusion/expr/src/type_coercion/binary.rs
@@ -120,7 +120,7 @@ fn signature(lhs: &DataType, op: &Operator, rhs: &DataType) 
-> Result<Signature>
         Operator::Divide|
         Operator::Modulo =>  {
             // TODO: this logic would be easier to follow if the functions 
were inlined
-            if let Some(ret) = mathematics_temporal_result_type(lhs, rhs) {
+            if let Some(ret) = mathematics_temporal_result_type(lhs, rhs, op) {
                 // Temporal arithmetic, e.g. Date32 + Interval
                 Ok(Signature{
                     lhs: lhs.clone(),
@@ -130,7 +130,7 @@ fn signature(lhs: &DataType, op: &Operator, rhs: &DataType) 
-> Result<Signature>
             } else if let Some(coerced) = temporal_coercion(lhs, rhs) {
                 // Temporal arithmetic by first coercing to a common time 
representation
                 // e.g. Date32 - Timestamp
-                let ret = mathematics_temporal_result_type(&coerced, 
&coerced).ok_or_else(|| {
+                let ret = mathematics_temporal_result_type(&coerced, &coerced, 
op).ok_or_else(|| {
                     DataFusionError::Plan(format!(
                         "Cannot get result type for temporal operation 
{coerced} {op} {coerced}"
                     ))
@@ -169,6 +169,7 @@ fn signature(lhs: &DataType, op: &Operator, rhs: &DataType) 
-> Result<Signature>
 fn mathematics_temporal_result_type(
     lhs_type: &DataType,
     rhs_type: &DataType,
+    op: &Operator,
 ) -> Option<DataType> {
     use arrow::datatypes::DataType::*;
     use arrow::datatypes::IntervalUnit::*;
@@ -176,12 +177,14 @@ fn mathematics_temporal_result_type(
 
     match (lhs_type, rhs_type) {
         // datetime +/- interval
-        (Interval(_), Timestamp(_, _)) => Some(rhs_type.clone()),
-        (Timestamp(_, _), Interval(_)) => Some(lhs_type.clone()),
-        (Interval(_), Date32) => Some(rhs_type.clone()),
-        (Date32, Interval(_)) => Some(lhs_type.clone()),
-        (Interval(_), Date64) => Some(rhs_type.clone()),
-        (Date64, Interval(_)) => Some(lhs_type.clone()),
+        (Timestamp(_, _) | Date32 | Date64, Interval(_)) => 
Some(lhs_type.clone()),
+        (Interval(_), Timestamp(_, _) | Date32 | Date64) => {
+            if matches!(op, Operator::Plus) {
+                Some(rhs_type.clone())
+            } else {
+                None
+            }
+        }
         // interval +/-
         (Interval(l), Interval(h)) if l == h => Some(lhs_type.clone()),
         (Interval(_), Interval(_)) => Some(Interval(MonthDayNano)),

Reply via email to