Improve test coverage of time_bucket_ng()

Also make the code more explicit about handling 'infinity' values.
This commit is contained in:
Aleksander Alekseev 2021-07-20 12:53:37 +03:00 committed by Aleksander Alekseev
parent 768ff54ae2
commit 00e4a91082
3 changed files with 217 additions and 14 deletions

View File

@ -310,16 +310,18 @@ ts_time_bucket_ng_timestamp(PG_FUNCTION_ARGS)
errmsg("interval can't combine months with minutes or hours")));
}
if (TIMESTAMP_NOT_FINITE(timestamp))
PG_RETURN_TIMESTAMP(timestamp);
/*
* Handle minutes, hours and days.
*/
Timestamp origin = (PG_NARGS() > 2 ? PG_GETARG_TIMESTAMP(2) : DEFAULT_ORIGIN);
if (TIMESTAMP_NOT_FINITE(origin))
PG_RETURN_TIMESTAMP(origin);
Timestamp result;
int64 period = get_interval_period_timestamp_units(interval);
if (TIMESTAMP_NOT_FINITE(timestamp))
PG_RETURN_TIMESTAMP(timestamp);
TIME_BUCKET_TS(period, timestamp, result, origin);
PG_RETURN_TIMESTAMP(result);
@ -403,6 +405,9 @@ ts_time_bucket_ng_date(PG_FUNCTION_ARGS)
if (PG_NARGS() > 2)
{
origin_date = PG_GETARG_DATUM(2);
if (DATE_NOT_FINITE(origin_date))
PG_RETURN_DATEADT(origin_date);
j2date(origin_date + POSTGRES_EPOCH_JDATE, &origin_year, &origin_month, &origin_day);
}

View File

@ -1241,13 +1241,6 @@ ERROR: origin must be before the given date
SELECT timescaledb_experimental.time_bucket_ng('1 month 3 hours', '2021-11-22' :: timestamp) AS result;
ERROR: interval can't combine months with minutes or hours
\set ON_ERROR_STOP 1
-- infinity
SELECT timescaledb_experimental.time_bucket_ng('1 year', 'infinity' :: date) AS result;
result
----------
infinity
(1 row)
-- wrappers
SELECT timescaledb_experimental.time_bucket_ng('1 year', '2021-11-22' :: timestamp) AS result;
result
@ -1273,6 +1266,175 @@ SELECT timescaledb_experimental.time_bucket_ng('1 year', '2021-11-22' :: timesta
Tue Jun 01 00:00:00 2021 EDT
(1 row)
-- null argument
SELECT timescaledb_experimental.time_bucket_ng('1 year', null :: date) AS result;
result
--------
(1 row)
SELECT timescaledb_experimental.time_bucket_ng('1 year', null :: timestamp) AS result;
result
--------
(1 row)
SELECT timescaledb_experimental.time_bucket_ng('1 year', null :: timestamptz) AS result;
result
--------
(1 row)
SELECT timescaledb_experimental.time_bucket_ng('1 year', null :: date, origin => '2021-06-01') AS result;
result
--------
(1 row)
SELECT timescaledb_experimental.time_bucket_ng('1 year', null :: timestamp, origin => '2021-06-01') AS result;
result
--------
(1 row)
SELECT timescaledb_experimental.time_bucket_ng('1 year', null :: timestamptz, origin => '2021-06-01') AS result;
result
--------
(1 row)
-- null interval
SELECT timescaledb_experimental.time_bucket_ng(null, '2021-07-12' :: date) AS result;
result
--------
(1 row)
SELECT timescaledb_experimental.time_bucket_ng(null, '2021-07-12 12:34:56' :: timestamp) AS result;
result
--------
(1 row)
SELECT timescaledb_experimental.time_bucket_ng(null, '2021-07-12 12:34:56' :: timestamptz) AS result;
result
--------
(1 row)
SELECT timescaledb_experimental.time_bucket_ng(null, '2021-07-12' :: date, origin => '2021-06-01') AS result;
result
--------
(1 row)
SELECT timescaledb_experimental.time_bucket_ng(null, '2021-07-12 12:34:56' :: timestamp, origin => '2021-06-01') AS result;
result
--------
(1 row)
SELECT timescaledb_experimental.time_bucket_ng(null, '2021-07-12 12:34:56' :: timestamptz, origin => '2021-06-01') AS result;
result
--------
(1 row)
-- null origin
SELECT timescaledb_experimental.time_bucket_ng('1 year', '2021-07-12' :: date, origin => null) AS result;
result
--------
(1 row)
SELECT timescaledb_experimental.time_bucket_ng('1 year', '2021-07-12 12:34:56' :: timestamp, origin => null) AS result;
result
--------
(1 row)
SELECT timescaledb_experimental.time_bucket_ng('1 year', '2021-07-12 12:34:56' :: timestamptz, origin => null) AS result;
result
--------
(1 row)
-- infinity argument
SELECT timescaledb_experimental.time_bucket_ng('1 year', 'infinity' :: date) AS result;
result
----------
infinity
(1 row)
SELECT timescaledb_experimental.time_bucket_ng('1 year', 'infinity' :: timestamp) AS result;
result
----------
infinity
(1 row)
SELECT timescaledb_experimental.time_bucket_ng('1 year', 'infinity' :: timestamptz) AS result;
result
----------
infinity
(1 row)
SELECT timescaledb_experimental.time_bucket_ng('1 year', 'infinity' :: date, origin => '2021-06-01') AS result;
result
----------
infinity
(1 row)
SELECT timescaledb_experimental.time_bucket_ng('1 year', 'infinity' :: timestamp, origin => '2021-06-01') AS result;
result
----------
infinity
(1 row)
SELECT timescaledb_experimental.time_bucket_ng('1 year', 'infinity' :: timestamptz, origin => '2021-06-01') AS result;
result
----------
infinity
(1 row)
-- test for specific code path: hours/minutes/seconds interval and timestamp argument
SELECT timescaledb_experimental.time_bucket_ng('12 hours', 'infinity' :: timestamp) AS result;
result
----------
infinity
(1 row)
SELECT timescaledb_experimental.time_bucket_ng('12 hours', 'infinity' :: timestamp, origin => '2021-06-01') AS result;
result
----------
infinity
(1 row)
-- infinite origin
SELECT timescaledb_experimental.time_bucket_ng('1 year', '2021-07-12' :: date, origin => 'infinity') AS result;
result
----------
infinity
(1 row)
SELECT timescaledb_experimental.time_bucket_ng('1 year', '2021-07-12 12:34:56' :: timestamp, origin => 'infinity') AS result;
result
----------
infinity
(1 row)
SELECT timescaledb_experimental.time_bucket_ng('1 year', '2021-07-12 12:34:56' :: timestamptz, origin => 'infinity') AS result;
result
----------
infinity
(1 row)
-- test for specific code path: hours/minutes/seconds interval and timestamp argument
SELECT timescaledb_experimental.time_bucket_ng('12 hours', '2021-07-12 12:34:56' :: timestamp, origin => 'infinity') AS result;
result
----------
infinity
(1 row)
-- Make sure time_bucket_ng() supports seconds, minutes, and hours.
-- We happen to know that the internal implementation is the same
-- as for time_bucket(), thus there is no reason to execute all the tests

View File

@ -612,15 +612,51 @@ SELECT timescaledb_experimental.time_bucket_ng('1 day', '2000-01-02' :: date, or
SELECT timescaledb_experimental.time_bucket_ng('1 month 3 hours', '2021-11-22' :: timestamp) AS result;
\set ON_ERROR_STOP 1
-- infinity
SELECT timescaledb_experimental.time_bucket_ng('1 year', 'infinity' :: date) AS result;
-- wrappers
SELECT timescaledb_experimental.time_bucket_ng('1 year', '2021-11-22' :: timestamp) AS result;
SELECT timescaledb_experimental.time_bucket_ng('1 year', '2021-11-22' :: timestamptz) AS result;
SELECT timescaledb_experimental.time_bucket_ng('1 year', '2021-11-22' :: timestamp, origin => '2021-06-01') AS result;
SELECT timescaledb_experimental.time_bucket_ng('1 year', '2021-11-22' :: timestamptz, origin => '2021-06-01') AS result;
-- null argument
SELECT timescaledb_experimental.time_bucket_ng('1 year', null :: date) AS result;
SELECT timescaledb_experimental.time_bucket_ng('1 year', null :: timestamp) AS result;
SELECT timescaledb_experimental.time_bucket_ng('1 year', null :: timestamptz) AS result;
SELECT timescaledb_experimental.time_bucket_ng('1 year', null :: date, origin => '2021-06-01') AS result;
SELECT timescaledb_experimental.time_bucket_ng('1 year', null :: timestamp, origin => '2021-06-01') AS result;
SELECT timescaledb_experimental.time_bucket_ng('1 year', null :: timestamptz, origin => '2021-06-01') AS result;
-- null interval
SELECT timescaledb_experimental.time_bucket_ng(null, '2021-07-12' :: date) AS result;
SELECT timescaledb_experimental.time_bucket_ng(null, '2021-07-12 12:34:56' :: timestamp) AS result;
SELECT timescaledb_experimental.time_bucket_ng(null, '2021-07-12 12:34:56' :: timestamptz) AS result;
SELECT timescaledb_experimental.time_bucket_ng(null, '2021-07-12' :: date, origin => '2021-06-01') AS result;
SELECT timescaledb_experimental.time_bucket_ng(null, '2021-07-12 12:34:56' :: timestamp, origin => '2021-06-01') AS result;
SELECT timescaledb_experimental.time_bucket_ng(null, '2021-07-12 12:34:56' :: timestamptz, origin => '2021-06-01') AS result;
-- null origin
SELECT timescaledb_experimental.time_bucket_ng('1 year', '2021-07-12' :: date, origin => null) AS result;
SELECT timescaledb_experimental.time_bucket_ng('1 year', '2021-07-12 12:34:56' :: timestamp, origin => null) AS result;
SELECT timescaledb_experimental.time_bucket_ng('1 year', '2021-07-12 12:34:56' :: timestamptz, origin => null) AS result;
-- infinity argument
SELECT timescaledb_experimental.time_bucket_ng('1 year', 'infinity' :: date) AS result;
SELECT timescaledb_experimental.time_bucket_ng('1 year', 'infinity' :: timestamp) AS result;
SELECT timescaledb_experimental.time_bucket_ng('1 year', 'infinity' :: timestamptz) AS result;
SELECT timescaledb_experimental.time_bucket_ng('1 year', 'infinity' :: date, origin => '2021-06-01') AS result;
SELECT timescaledb_experimental.time_bucket_ng('1 year', 'infinity' :: timestamp, origin => '2021-06-01') AS result;
SELECT timescaledb_experimental.time_bucket_ng('1 year', 'infinity' :: timestamptz, origin => '2021-06-01') AS result;
-- test for specific code path: hours/minutes/seconds interval and timestamp argument
SELECT timescaledb_experimental.time_bucket_ng('12 hours', 'infinity' :: timestamp) AS result;
SELECT timescaledb_experimental.time_bucket_ng('12 hours', 'infinity' :: timestamp, origin => '2021-06-01') AS result;
-- infinite origin
SELECT timescaledb_experimental.time_bucket_ng('1 year', '2021-07-12' :: date, origin => 'infinity') AS result;
SELECT timescaledb_experimental.time_bucket_ng('1 year', '2021-07-12 12:34:56' :: timestamp, origin => 'infinity') AS result;
SELECT timescaledb_experimental.time_bucket_ng('1 year', '2021-07-12 12:34:56' :: timestamptz, origin => 'infinity') AS result;
-- test for specific code path: hours/minutes/seconds interval and timestamp argument
SELECT timescaledb_experimental.time_bucket_ng('12 hours', '2021-07-12 12:34:56' :: timestamp, origin => 'infinity') AS result;
-- Make sure time_bucket_ng() supports seconds, minutes, and hours.
-- We happen to know that the internal implementation is the same
-- as for time_bucket(), thus there is no reason to execute all the tests