From 61d9fc7e9e3c0d78cafade7d0c3e12ee7df4f00f Mon Sep 17 00:00:00 2001 From: Martin Hilton Date: Tue, 17 Oct 2023 18:24:32 +0100 Subject: [PATCH 1/3] feat(7849): coerce TIMESTAMP to TIMESTAMPTZ Add coercion rules to support coercion from timestamp types without a timezone to a timestamp with a timezone. Like with the coercion of strings or numeric constants, when a function requires the TIMEZONE_WILDCARD placeholder timezone "+00" will be used as the timezone offset. --- datafusion/expr/src/type_coercion/functions.rs | 4 ++-- datafusion/sqllogictest/test_files/timestamps.slt | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/datafusion/expr/src/type_coercion/functions.rs b/datafusion/expr/src/type_coercion/functions.rs index 17ca40236d41..b387667ad107 100644 --- a/datafusion/expr/src/type_coercion/functions.rs +++ b/datafusion/expr/src/type_coercion/functions.rs @@ -228,7 +228,7 @@ fn coerced_from<'a>( Timestamp(_, Some(from_tz)) => { Some(Timestamp(unit.clone(), Some(from_tz.clone()))) } - Null | Date32 | Utf8 | LargeUtf8 => { + Null | Date32 | Utf8 | LargeUtf8 | Timestamp(_, None) => { // In the absence of any other information assume the time zone is "+00" (UTC). Some(Timestamp(unit.clone(), Some("+00".into()))) } @@ -238,7 +238,7 @@ fn coerced_from<'a>( Timestamp(_, Some(_)) if matches!( type_from, - Null | Timestamp(_, Some(_)) | Date32 | Utf8 | LargeUtf8 + Null | Timestamp(_, _) | Date32 | Utf8 | LargeUtf8 ) => { Some(type_into.clone()) diff --git a/datafusion/sqllogictest/test_files/timestamps.slt b/datafusion/sqllogictest/test_files/timestamps.slt index edafe18caab5..e37a1b0771d5 100644 --- a/datafusion/sqllogictest/test_files/timestamps.slt +++ b/datafusion/sqllogictest/test_files/timestamps.slt @@ -1389,6 +1389,12 @@ SELECT date_bin('1 day', TIMESTAMPTZ '2022-01-01 20:10:00Z', TIMESTAMPTZ '2020-0 ---- 2022-01-02T00:00:00+07:00 +# coerce TIMESTAMP to TIMESTAMPTZ +query P +SELECT date_bin('1 day', TIMESTAMPTZ '2022-01-01 20:10:00Z', TIMESTAMP '2020-01-01') +---- +2022-01-01T07:00:00+07:00 + # postgresql: 1 query R SELECT date_part('hour', TIMESTAMPTZ '2000-01-01T01:01:01') as part From 3ed6adbed6afc8584a0355f7bf86631018e8ee8e Mon Sep 17 00:00:00 2001 From: Martin Hilton Date: Wed, 18 Oct 2023 10:40:43 +0100 Subject: [PATCH 2/3] review comments Add additional SQL logic test suggested in review. --- datafusion/sqllogictest/test_files/timestamps.slt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/datafusion/sqllogictest/test_files/timestamps.slt b/datafusion/sqllogictest/test_files/timestamps.slt index e37a1b0771d5..72cbaa012a78 100644 --- a/datafusion/sqllogictest/test_files/timestamps.slt +++ b/datafusion/sqllogictest/test_files/timestamps.slt @@ -1764,3 +1764,10 @@ query T SELECT arrow_typeof(date_bin(INTERVAL '1 day', time, '1970-01-01T00:00:00+05:00')) FROM foo LIMIT 1 ---- Timestamp(Nanosecond, Some("+05:00")) + + +# timestamp comparison with and without timezone +query B +SELECT TIMESTAMPTZ '2022-01-01 20:10:00Z' = TIMESTAMP '2020-01-01' +---- +false From 9faaa94751b8ff3d35dc7bfbeafb6854c95bbc17 Mon Sep 17 00:00:00 2001 From: Martin Hilton Date: Wed, 18 Oct 2023 14:37:47 +0100 Subject: [PATCH 3/3] more review suggestions Add a positive test case for TIMESTAMPTZ and TIMESTAMP comparison. --- datafusion/sqllogictest/test_files/timestamps.slt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/datafusion/sqllogictest/test_files/timestamps.slt b/datafusion/sqllogictest/test_files/timestamps.slt index 72cbaa012a78..fea61b076ebc 100644 --- a/datafusion/sqllogictest/test_files/timestamps.slt +++ b/datafusion/sqllogictest/test_files/timestamps.slt @@ -1771,3 +1771,8 @@ query B SELECT TIMESTAMPTZ '2022-01-01 20:10:00Z' = TIMESTAMP '2020-01-01' ---- false + +query B +SELECT TIMESTAMPTZ '2020-01-01 00:00:00Z' = TIMESTAMP '2020-01-01' +---- +true