Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions src/expr/src/scalar/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2024,10 +2024,15 @@ where
)
})?;

let mut tm_delta = tm_diff - tm_diff % stride_ns;

if sub_stride {
tm_delta -= stride_ns;
let remainder = tm_diff % stride_ns;
let mut tm_delta = tm_diff - remainder;

if sub_stride && remainder != 0 {
tm_delta = tm_delta.checked_sub(stride_ns).ok_or_else(|| {
EvalError::DateBinOutOfRange(
"source and origin must not differ more than 2^63 nanoseconds".into(),
)
})?;
}

let res = origin
Expand Down
26 changes: 26 additions & 0 deletions test/sqllogictest/timestamp.slt
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,32 @@ SELECT date_bin('5 min'::interval, timestamp '2020-02-01 01:01:01', timestamp '2
----
2020-02-01 00:57:30

# source before origin, exactly on a bin boundary
query T
SELECT date_bin('5 min'::interval, timestamp '1969-12-31 23:55:00', timestamp '1970-01-01 00:00:00');
----
1969-12-31 23:55:00

query T
SELECT date_bin('1 hour'::interval, timestamp '1970-01-01 00:00:00', timestamp '1970-01-01 01:00:00');
----
1970-01-01 00:00:00

query T
SELECT date_bin('10 min'::interval, timestamp '1969-12-31 23:40:00', timestamp '1970-01-01 00:00:00');
----
1969-12-31 23:40:00

# source before origin, not on a bin boundary
query T
SELECT date_bin('5 min'::interval, timestamp '1969-12-31 23:56:30', timestamp '1970-01-01 00:00:00');
----
1969-12-31 23:55:00

# i64::MIN nanosecond boundary must error, not silently wrap
query error source and origin must not differ more than 2\^63 nanoseconds
SELECT date_bin('1 hour'::interval, timestamp '1677-09-21 00:12:43.145224192', timestamp '1970-01-01 00:00:00');

# disallow > day intervals
query error timestamps cannot be binned into intervals containing months or years
SELECT date_bin('5 months'::interval, timestamp '2020-02-01 01:01:01', timestamp '2001-01-01');
Expand Down
26 changes: 26 additions & 0 deletions test/sqllogictest/timestamptz.slt
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,32 @@ SELECT date_bin('5 min'::interval, timestamptz '2020-02-01 01:01:01+00', timesta
----
2020-02-01 00:57:30+00

# source before origin, exactly on a bin boundary
query T
SELECT date_bin('5 min'::interval, timestamptz '1969-12-31 23:55:00+00', timestamptz '1970-01-01 00:00:00+00');
----
1969-12-31 23:55:00+00

query T
SELECT date_bin('1 hour'::interval, timestamptz '1970-01-01 00:00:00+00', timestamptz '1970-01-01 01:00:00+00');
----
1970-01-01 00:00:00+00

query T
SELECT date_bin('10 min'::interval, timestamptz '1969-12-31 23:40:00+00', timestamptz '1970-01-01 00:00:00+00');
----
1969-12-31 23:40:00+00

# source before origin, not on a bin boundary
query T
SELECT date_bin('5 min'::interval, timestamptz '1969-12-31 23:56:30+00', timestamptz '1970-01-01 00:00:00+00');
----
1969-12-31 23:55:00+00

# i64::MIN nanosecond boundary must error, not silently wrap
query error source and origin must not differ more than 2\^63 nanoseconds
SELECT date_bin('1 hour'::interval, timestamptz '1677-09-21 00:12:43.145224192+00', timestamptz '1970-01-01 00:00:00+00');

# disallow > day intervals
query error timestamps cannot be binned into intervals containing months or years
SELECT date_bin('5 months'::interval, timestamptz '2020-02-01 01:01:01+00', timestamptz '2001-01-01');
Expand Down
Loading