Skip to content

Commit 7c7e677

Browse files
committed
Fix discrepancy in Float64 to timestamp(9) casts
Before the change, when casting `Float64` value to `Timestamp(Nanosecond, None)`, the result would depend on whether the source value is constant-foldable scalar. This is because `ScalarValue.cast_to` had a special treatment for that source & destination type pair, producing a different result from the canonical one.
1 parent 7cdac33 commit 7c7e677

File tree

2 files changed

+89
-9
lines changed

2 files changed

+89
-9
lines changed

datafusion/common/src/scalar/mod.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3060,11 +3060,6 @@ impl ScalarValue {
30603060
cast_options: &CastOptions<'static>,
30613061
) -> Result<Self> {
30623062
let scalar_array = match (self, target_type) {
3063-
(
3064-
ScalarValue::Float64(Some(float_ts)),
3065-
DataType::Timestamp(TimeUnit::Nanosecond, None),
3066-
) => ScalarValue::Int64(Some((float_ts * 1_000_000_000_f64).trunc() as i64))
3067-
.to_array()?,
30683063
(
30693064
ScalarValue::Decimal128(Some(decimal_value), _, scale),
30703065
DataType::Timestamp(time_unit, None),

datafusion/sqllogictest/test_files/timestamps.slt

Lines changed: 89 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,91 @@ SELECT TIMESTAMPTZ '2000-01-01T01:01:01'
176176
2000-01-01T01:01:01Z
177177

178178

179+
##########
180+
## cast tests
181+
##########
182+
183+
query PPPBB
184+
SELECT *, t1 = t2, t1 = t3
185+
FROM (SELECT
186+
(SELECT CAST(CAST(1 AS double) AS timestamp(0))) AS t1,
187+
(SELECT CAST(CAST(one AS double) AS timestamp(0)) FROM (SELECT 1 AS one)) AS t2,
188+
(SELECT CAST(CAST(one AS double) AS timestamp(0)) FROM (VALUES (1)) t(one)) AS t3
189+
)
190+
----
191+
1970-01-01T00:00:01 1970-01-01T00:00:01 1970-01-01T00:00:01 true true
192+
193+
query PPPBB
194+
SELECT *, t1 = t2, t1 = t3
195+
FROM (SELECT
196+
(SELECT CAST(CAST(1 AS double) AS timestamp(3))) AS t1,
197+
(SELECT CAST(CAST(one AS double) AS timestamp(3)) FROM (SELECT 1 AS one)) AS t2,
198+
(SELECT CAST(CAST(one AS double) AS timestamp(3)) FROM (VALUES (1)) t(one)) AS t3
199+
)
200+
----
201+
1970-01-01T00:00:00.001 1970-01-01T00:00:00.001 1970-01-01T00:00:00.001 true true
202+
203+
query PPPBB
204+
SELECT *, t1 = t2, t1 = t3
205+
FROM (SELECT
206+
(SELECT CAST(CAST(1 AS double) AS timestamp(6))) AS t1,
207+
(SELECT CAST(CAST(one AS double) AS timestamp(6)) FROM (SELECT 1 AS one)) AS t2,
208+
(SELECT CAST(CAST(one AS double) AS timestamp(6)) FROM (VALUES (1)) t(one)) AS t3
209+
)
210+
----
211+
1970-01-01T00:00:00.000001 1970-01-01T00:00:00.000001 1970-01-01T00:00:00.000001 true true
212+
213+
query PPPBB
214+
SELECT *, t1 = t2, t1 = t3
215+
FROM (SELECT
216+
(SELECT CAST(CAST(1 AS double) AS timestamp(9))) AS t1,
217+
(SELECT CAST(CAST(one AS double) AS timestamp(9)) FROM (SELECT 1 AS one)) AS t2,
218+
(SELECT CAST(CAST(one AS double) AS timestamp(9)) FROM (VALUES (1)) t(one)) AS t3
219+
)
220+
----
221+
1970-01-01T00:00:00.000000001 1970-01-01T00:00:00.000000001 1970-01-01T00:00:00.000000001 true true
222+
223+
query PPPBB
224+
SELECT *, t1 = t2, t1 = t3
225+
FROM (SELECT
226+
(SELECT CAST(CAST(1.125 AS double) AS timestamp(0))) AS t1,
227+
(SELECT CAST(CAST(one_and_a_bit AS double) AS timestamp(0)) FROM (SELECT 1.125 AS one_and_a_bit)) AS t2,
228+
(SELECT CAST(CAST(one_and_a_bit AS double) AS timestamp(0)) FROM (VALUES (1.125)) t(one_and_a_bit)) AS t3
229+
)
230+
----
231+
1970-01-01T00:00:01 1970-01-01T00:00:01 1970-01-01T00:00:01 true true
232+
233+
query PPPBB
234+
SELECT *, t1 = t2, t1 = t3
235+
FROM (SELECT
236+
(SELECT CAST(CAST(1.125 AS double) AS timestamp(3))) AS t1,
237+
(SELECT CAST(CAST(one_and_a_bit AS double) AS timestamp(3)) FROM (SELECT 1.125 AS one_and_a_bit)) AS t2,
238+
(SELECT CAST(CAST(one_and_a_bit AS double) AS timestamp(3)) FROM (VALUES (1.125)) t(one_and_a_bit)) AS t3
239+
)
240+
----
241+
1970-01-01T00:00:00.001 1970-01-01T00:00:00.001 1970-01-01T00:00:00.001 true true
242+
243+
query PPPBB
244+
SELECT *, t1 = t2, t1 = t3
245+
FROM (SELECT
246+
(SELECT CAST(CAST(1.125 AS double) AS timestamp(6))) AS t1,
247+
(SELECT CAST(CAST(one_and_a_bit AS double) AS timestamp(6)) FROM (SELECT 1.125 AS one_and_a_bit)) AS t2,
248+
(SELECT CAST(CAST(one_and_a_bit AS double) AS timestamp(6)) FROM (VALUES (1.125)) t(one_and_a_bit)) AS t3
249+
)
250+
----
251+
1970-01-01T00:00:00.000001 1970-01-01T00:00:00.000001 1970-01-01T00:00:00.000001 true true
252+
253+
query PPPBB
254+
SELECT *, t1 = t2, t1 = t3
255+
FROM (SELECT
256+
(SELECT CAST(CAST(1.125 AS double) AS timestamp(9))) AS t1,
257+
(SELECT CAST(CAST(one_and_a_bit AS double) AS timestamp(9)) FROM (SELECT 1.125 AS one_and_a_bit)) AS t2,
258+
(SELECT CAST(CAST(one_and_a_bit AS double) AS timestamp(9)) FROM (VALUES (1.125)) t(one_and_a_bit)) AS t3
259+
)
260+
----
261+
1970-01-01T00:00:00.000000001 1970-01-01T00:00:00.000000001 1970-01-01T00:00:00.000000001 true true
262+
263+
179264
##########
180265
## to_timestamp tests
181266
##########
@@ -394,12 +479,12 @@ SELECT COUNT(*) FROM ts_data_secs where ts > to_timestamp_seconds('2020-09-08 12
394479
query PPP
395480
SELECT to_timestamp(1.1) as c1, cast(1.1 as timestamp) as c2, 1.1::timestamp as c3;
396481
----
397-
1970-01-01T00:00:01.100 1970-01-01T00:00:01.100 1970-01-01T00:00:01.100
482+
1970-01-01T00:00:00.000000001 1970-01-01T00:00:00.000000001 1970-01-01T00:00:00.000000001
398483

399484
query PPP
400485
SELECT to_timestamp(-1.1) as c1, cast(-1.1 as timestamp) as c2, (-1.1)::timestamp as c3;
401486
----
402-
1969-12-31T23:59:58.900 1969-12-31T23:59:58.900 1969-12-31T23:59:58.900
487+
1969-12-31T23:59:59.999999999 1969-12-31T23:59:59.999999999 1969-12-31T23:59:59.999999999
403488

404489
query PPP
405490
SELECT to_timestamp(0.0) as c1, cast(0.0 as timestamp) as c2, 0.0::timestamp as c3;
@@ -409,12 +494,12 @@ SELECT to_timestamp(0.0) as c1, cast(0.0 as timestamp) as c2, 0.0::timestamp as
409494
query PPP
410495
SELECT to_timestamp(1.23456789) as c1, cast(1.23456789 as timestamp) as c2, 1.23456789::timestamp as c3;
411496
----
412-
1970-01-01T00:00:01.234567890 1970-01-01T00:00:01.234567890 1970-01-01T00:00:01.234567890
497+
1970-01-01T00:00:00.000000001 1970-01-01T00:00:00.000000001 1970-01-01T00:00:00.000000001
413498

414499
query PPP
415500
SELECT to_timestamp(123456789.123456789) as c1, cast(123456789.123456789 as timestamp) as c2, 123456789.123456789::timestamp as c3;
416501
----
417-
1973-11-29T21:33:09.123456784 1973-11-29T21:33:09.123456784 1973-11-29T21:33:09.123456784
502+
1970-01-01T00:00:00.123456789 1970-01-01T00:00:00.123456789 1970-01-01T00:00:00.123456789
418503

419504
# to_timestamp Decimal128 inputs
420505

0 commit comments

Comments
 (0)