Move time_bucket epoch to a Monday

Since Monday is the ISO start of the week, it makes sense to move
the time_bucket epoch to start on a Monday. Before the epoch was the
same as the Postgres epoch (2000-01-01, a Saturday).
This commit is contained in:
Matvey Arye 2018-09-28 09:24:15 -04:00 committed by Matvey Arye
parent ba88f481cf
commit e74be30925
5 changed files with 187 additions and 35 deletions

View File

@ -283,10 +283,24 @@ ts_timestamp_bucket(PG_FUNCTION_ARGS)
Timestamp timestamp = PG_GETARG_TIMESTAMP(1);
Timestamp result;
int64 period = -1;
/* The offset moves the epoch to start on a monday the default postgres epoch starts on a saturday.
* This makes time-buckets by a week more intuitive.
*/
#ifdef HAVE_INT64_TIMESTAMP
int64 offset = 2*USECS_PER_DAY;
#else
double offset = 2*SECS_PER_DAY;
#endif
if (TIMESTAMP_NOT_FINITE(timestamp))
PG_RETURN_TIMESTAMP(timestamp);
if(timestamp < DT_NOBEGIN + offset)
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("timestamp out of range")));
timestamp -= offset;
period = get_interval_period_timestamp_units(interval);
/* result = (timestamp / period) * period */
TMODULO(timestamp, result, period);
@ -304,6 +318,7 @@ ts_timestamp_bucket(PG_FUNCTION_ARGS)
{
result *= period;
}
result += offset;
PG_RETURN_TIMESTAMP(result);
}
@ -315,10 +330,25 @@ ts_timestamptz_bucket(PG_FUNCTION_ARGS)
TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(1);
TimestampTz result;
int64 period = -1;
/* The offset moves the epoch to start on a monday the default postgres epoch starts on a saturday.
* This makes time-buckets by a week more intuitive.
*/
#ifdef HAVE_INT64_TIMESTAMP
int64 offset = 2*USECS_PER_DAY;
#else
double offset = 2*SECS_PER_DAY;
#endif
if (TIMESTAMP_NOT_FINITE(timestamp))
PG_RETURN_TIMESTAMPTZ(timestamp);
if(timestamp < DT_NOBEGIN + offset)
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("timestamp out of range")));
timestamp -= offset;
period = get_interval_period_timestamp_units(interval);
/* result = (timestamp / period) * period */
TMODULO(timestamp, result, period);
@ -336,6 +366,7 @@ ts_timestamptz_bucket(PG_FUNCTION_ARGS)
{
result *= period;
}
result += offset;
PG_RETURN_TIMESTAMPTZ(result);
}

View File

@ -404,12 +404,12 @@ psql:include/append.sql:166: NOTICE: Stable function now_s() called!
psql:include/append.sql:166: NOTICE: Stable function now_s() called!
btime | value
------------------------------+-------
Wed Mar 01 16:00:00 2017 PST | 22.5
Fri Mar 31 17:00:00 2017 PDT |
Sun Apr 30 17:00:00 2017 PDT | 25.7
Tue May 30 17:00:00 2017 PDT |
Thu Jun 29 17:00:00 2017 PDT |
Sat Jul 29 17:00:00 2017 PDT | 34.1
Fri Mar 03 16:00:00 2017 PST | 22.5
Sun Apr 02 17:00:00 2017 PDT |
Tue May 02 17:00:00 2017 PDT | 25.7
Thu Jun 01 17:00:00 2017 PDT |
Sat Jul 01 17:00:00 2017 PDT |
Mon Jul 31 17:00:00 2017 PDT | 34.1
(6 rows)
-- Create another hypertable to join with

View File

@ -434,12 +434,12 @@ psql:include/append.sql:166: NOTICE: Stable function now_s() called!
psql:include/append.sql:166: NOTICE: Stable function now_s() called!
btime | value
------------------------------+-------
Wed Mar 01 16:00:00 2017 PST | 22.5
Fri Mar 31 17:00:00 2017 PDT |
Sun Apr 30 17:00:00 2017 PDT | 25.7
Tue May 30 17:00:00 2017 PDT |
Thu Jun 29 17:00:00 2017 PDT |
Sat Jul 29 17:00:00 2017 PDT | 34.1
Fri Mar 03 16:00:00 2017 PST | 22.5
Sun Apr 02 17:00:00 2017 PDT |
Tue May 02 17:00:00 2017 PDT | 25.7
Thu Jun 01 17:00:00 2017 PDT |
Sat Jul 01 17:00:00 2017 PDT |
Mon Jul 31 17:00:00 2017 PDT | 34.1
(6 rows)
-- Create another hypertable to join with

View File

@ -677,21 +677,6 @@ FROM unnest(ARRAY[
(2 rows)
SELECT time, time_bucket(INTERVAL '4 day', time::date)
FROM unnest(ARRAY[
date '2017-11-02',
date '2017-11-03',
date '2017-11-06',
date '2017-11-07'
]) AS time;
time | time_bucket
------------+-------------
11-02-2017 | 10-30-2017
11-03-2017 | 11-03-2017
11-06-2017 | 11-03-2017
11-07-2017 | 11-07-2017
(4 rows)
SELECT time, time_bucket(INTERVAL '4 day', time::date, INTERVAL '2 day')
FROM unnest(ARRAY[
date '2017-11-04',
date '2017-11-05',
@ -706,6 +691,100 @@ FROM unnest(ARRAY[
11-09-2017 | 11-09-2017
(4 rows)
SELECT time, time_bucket(INTERVAL '4 day', time::date, INTERVAL '2 day')
FROM unnest(ARRAY[
date '2017-11-06',
date '2017-11-07',
date '2017-11-10',
date '2017-11-11'
]) AS time;
time | time_bucket
------------+-------------
11-06-2017 | 11-03-2017
11-07-2017 | 11-07-2017
11-10-2017 | 11-07-2017
11-11-2017 | 11-11-2017
(4 rows)
-- 2019-09-24 is a Monday.
SELECT time, time_bucket(INTERVAL '1 week', time::date)
FROM unnest(ARRAY[
date '2018-09-16',
date '2018-09-17',
date '2018-09-23',
date '2018-09-24'
]) AS time;
time | time_bucket
------------+-------------
09-16-2018 | 09-10-2018
09-17-2018 | 09-17-2018
09-23-2018 | 09-17-2018
09-24-2018 | 09-24-2018
(4 rows)
SELECT time, time_bucket(INTERVAL '1 week', time)
FROM unnest(ARRAY[
timestamp without time zone '2018-09-16',
timestamp without time zone '2018-09-17',
timestamp without time zone '2018-09-23',
timestamp without time zone '2018-09-24'
]) AS time;
time | time_bucket
--------------------------+--------------------------
Sun Sep 16 00:00:00 2018 | Mon Sep 10 00:00:00 2018
Mon Sep 17 00:00:00 2018 | Mon Sep 17 00:00:00 2018
Sun Sep 23 00:00:00 2018 | Mon Sep 17 00:00:00 2018
Mon Sep 24 00:00:00 2018 | Mon Sep 24 00:00:00 2018
(4 rows)
SELECT time, time_bucket(INTERVAL '1 week', time)
FROM unnest(ARRAY[
timestamp with time zone '2018-09-16',
timestamp with time zone '2018-09-17',
timestamp with time zone '2018-09-23',
timestamp with time zone '2018-09-24'
]) AS time;
time | time_bucket
------------------------------+------------------------------
Sun Sep 16 00:00:00 2018 EDT | Sun Sep 09 20:00:00 2018 EDT
Mon Sep 17 00:00:00 2018 EDT | Sun Sep 16 20:00:00 2018 EDT
Sun Sep 23 00:00:00 2018 EDT | Sun Sep 16 20:00:00 2018 EDT
Mon Sep 24 00:00:00 2018 EDT | Sun Sep 23 20:00:00 2018 EDT
(4 rows)
SELECT time, time_bucket(INTERVAL '1 week', time)
FROM unnest(ARRAY[
timestamp with time zone '-Infinity',
timestamp with time zone 'Infinity'
]) AS time;
time | time_bucket
-----------+-------------
-infinity | -infinity
infinity | infinity
(2 rows)
SELECT time, time_bucket(INTERVAL '1 week', time)
FROM unnest(ARRAY[
timestamp without time zone '-Infinity',
timestamp without time zone 'Infinity'
]) AS time;
time | time_bucket
-----------+-------------
-infinity | -infinity
infinity | infinity
(2 rows)
SELECT time, time_bucket(INTERVAL '1 week', time)
FROM unnest(ARRAY[
timestamp without time zone '4714-11-24 01:01:01.0 BC',
timestamp without time zone '294276-12-31 23:59:59.9999'
]) AS time;
time | time_bucket
---------------------------------+-----------------------------
Mon Nov 24 01:01:01 4714 BC | Mon Nov 24 00:00:00 4714 BC
Sun Dec 31 23:59:59.9999 294276 | Mon Dec 25 00:00:00 294276
(2 rows)
-------------------------------------
--- Test time input functions --
-------------------------------------

View File

@ -400,14 +400,6 @@ FROM unnest(ARRAY[
]) AS time;
SELECT time, time_bucket(INTERVAL '4 day', time::date)
FROM unnest(ARRAY[
date '2017-11-02',
date '2017-11-03',
date '2017-11-06',
date '2017-11-07'
]) AS time;
SELECT time, time_bucket(INTERVAL '4 day', time::date, INTERVAL '2 day')
FROM unnest(ARRAY[
date '2017-11-04',
date '2017-11-05',
@ -415,7 +407,57 @@ FROM unnest(ARRAY[
date '2017-11-09'
]) AS time;
SELECT time, time_bucket(INTERVAL '4 day', time::date, INTERVAL '2 day')
FROM unnest(ARRAY[
date '2017-11-06',
date '2017-11-07',
date '2017-11-10',
date '2017-11-11'
]) AS time;
-- 2019-09-24 is a Monday.
SELECT time, time_bucket(INTERVAL '1 week', time::date)
FROM unnest(ARRAY[
date '2018-09-16',
date '2018-09-17',
date '2018-09-23',
date '2018-09-24'
]) AS time;
SELECT time, time_bucket(INTERVAL '1 week', time)
FROM unnest(ARRAY[
timestamp without time zone '2018-09-16',
timestamp without time zone '2018-09-17',
timestamp without time zone '2018-09-23',
timestamp without time zone '2018-09-24'
]) AS time;
SELECT time, time_bucket(INTERVAL '1 week', time)
FROM unnest(ARRAY[
timestamp with time zone '2018-09-16',
timestamp with time zone '2018-09-17',
timestamp with time zone '2018-09-23',
timestamp with time zone '2018-09-24'
]) AS time;
SELECT time, time_bucket(INTERVAL '1 week', time)
FROM unnest(ARRAY[
timestamp with time zone '-Infinity',
timestamp with time zone 'Infinity'
]) AS time;
SELECT time, time_bucket(INTERVAL '1 week', time)
FROM unnest(ARRAY[
timestamp without time zone '-Infinity',
timestamp without time zone 'Infinity'
]) AS time;
SELECT time, time_bucket(INTERVAL '1 week', time)
FROM unnest(ARRAY[
timestamp without time zone '4714-11-24 01:01:01.0 BC',
timestamp without time zone '294276-12-31 23:59:59.9999'
]) AS time;
-------------------------------------
--- Test time input functions --
-------------------------------------