mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-15 10:11:29 +08:00
The previous default of 30 days was typically too long for most starting use cases, which would lead users to have one large chunk that lacked some of the benefits of using TimescaleDB, at least for the initial chunk. This chunk size should be more reasonable, especially for initial workloads.
651 lines
25 KiB
Plaintext
651 lines
25 KiB
Plaintext
-- Utility function for grouping/slotting time with a given interval.
|
|
CREATE OR REPLACE FUNCTION date_group(
|
|
field timestamp,
|
|
group_interval interval
|
|
)
|
|
RETURNS timestamp LANGUAGE SQL STABLE AS
|
|
$BODY$
|
|
SELECT to_timestamp((EXTRACT(EPOCH from $1)::int /
|
|
EXTRACT(EPOCH from group_interval)::int) *
|
|
EXTRACT(EPOCH from group_interval)::int)::timestamp;
|
|
$BODY$;
|
|
CREATE TABLE PUBLIC."testNs" (
|
|
"timeCustom" TIMESTAMP NOT NULL,
|
|
device_id TEXT NOT NULL,
|
|
series_0 DOUBLE PRECISION NULL,
|
|
series_1 DOUBLE PRECISION NULL,
|
|
series_2 DOUBLE PRECISION NULL,
|
|
series_bool BOOLEAN NULL
|
|
);
|
|
CREATE INDEX ON PUBLIC."testNs" (device_id, "timeCustom" DESC NULLS LAST) WHERE device_id IS NOT NULL;
|
|
\c single :ROLE_SUPERUSER
|
|
CREATE SCHEMA "testNs" AUTHORIZATION :ROLE_DEFAULT_PERM_USER;
|
|
\c single :ROLE_DEFAULT_PERM_USER
|
|
SELECT * FROM create_hypertable('"public"."testNs"', 'timeCustom', 'device_id', 2, associated_schema_name=>'testNs' );
|
|
create_hypertable
|
|
-------------------
|
|
|
|
(1 row)
|
|
|
|
\c single
|
|
INSERT INTO PUBLIC."testNs"("timeCustom", device_id, series_0, series_1) VALUES
|
|
('2009-11-12T01:00:00+00:00', 'dev1', 1.5, 1),
|
|
('2009-11-12T01:00:00+00:00', 'dev1', 1.5, 2),
|
|
('2009-11-10T23:00:02+00:00', 'dev1', 2.5, 3);
|
|
INSERT INTO PUBLIC."testNs"("timeCustom", device_id, series_0, series_1) VALUES
|
|
('2009-11-10T23:00:00+00:00', 'dev2', 1.5, 1),
|
|
('2009-11-10T23:00:00+00:00', 'dev2', 1.5, 2);
|
|
SELECT * FROM PUBLIC."testNs";
|
|
timeCustom | device_id | series_0 | series_1 | series_2 | series_bool
|
|
--------------------------+-----------+----------+----------+----------+-------------
|
|
Thu Nov 12 01:00:00 2009 | dev1 | 1.5 | 1 | |
|
|
Thu Nov 12 01:00:00 2009 | dev1 | 1.5 | 2 | |
|
|
Tue Nov 10 23:00:02 2009 | dev1 | 2.5 | 3 | |
|
|
Tue Nov 10 23:00:00 2009 | dev2 | 1.5 | 1 | |
|
|
Tue Nov 10 23:00:00 2009 | dev2 | 1.5 | 2 | |
|
|
(5 rows)
|
|
|
|
SET client_min_messages = WARNING;
|
|
\echo 'The next 2 queries will differ in output between UTC and EST since the mod is on the 100th hour UTC'
|
|
The next 2 queries will differ in output between UTC and EST since the mod is on the 100th hour UTC
|
|
SET timezone = 'UTC';
|
|
SELECT date_group("timeCustom", '100 days') AS time, sum(series_0)
|
|
FROM PUBLIC."testNs" GROUP BY time ORDER BY time ASC;
|
|
time | sum
|
|
--------------------------+-----
|
|
Sun Sep 13 00:00:00 2009 | 8.5
|
|
(1 row)
|
|
|
|
SET timezone = 'EST';
|
|
SELECT date_group("timeCustom", '100 days') AS time, sum(series_0)
|
|
FROM PUBLIC."testNs" GROUP BY time ORDER BY time ASC;
|
|
time | sum
|
|
--------------------------+-----
|
|
Sat Sep 12 19:00:00 2009 | 8.5
|
|
(1 row)
|
|
|
|
\echo 'The rest of the queries will be the same in output between UTC and EST'
|
|
The rest of the queries will be the same in output between UTC and EST
|
|
SET timezone = 'UTC';
|
|
SELECT date_group("timeCustom", '1 day') AS time, sum(series_0)
|
|
FROM PUBLIC."testNs" GROUP BY time ORDER BY time ASC;
|
|
time | sum
|
|
--------------------------+-----
|
|
Tue Nov 10 00:00:00 2009 | 5.5
|
|
Thu Nov 12 00:00:00 2009 | 3
|
|
(2 rows)
|
|
|
|
SET timezone = 'EST';
|
|
SELECT date_group("timeCustom", '1 day') AS time, sum(series_0)
|
|
FROM PUBLIC."testNs" GROUP BY time ORDER BY time ASC;
|
|
time | sum
|
|
--------------------------+-----
|
|
Mon Nov 09 19:00:00 2009 | 5.5
|
|
Wed Nov 11 19:00:00 2009 | 3
|
|
(2 rows)
|
|
|
|
SET timezone = 'UTC';
|
|
SELECT *
|
|
FROM PUBLIC."testNs"
|
|
WHERE "timeCustom" >= TIMESTAMP '2009-11-10T23:00:00'
|
|
AND "timeCustom" < TIMESTAMP '2009-11-12T01:00:00' ORDER BY "timeCustom" DESC;
|
|
timeCustom | device_id | series_0 | series_1 | series_2 | series_bool
|
|
--------------------------+-----------+----------+----------+----------+-------------
|
|
Tue Nov 10 23:00:02 2009 | dev1 | 2.5 | 3 | |
|
|
Tue Nov 10 23:00:00 2009 | dev2 | 1.5 | 1 | |
|
|
Tue Nov 10 23:00:00 2009 | dev2 | 1.5 | 2 | |
|
|
(3 rows)
|
|
|
|
SET timezone = 'EST';
|
|
SELECT *
|
|
FROM PUBLIC."testNs"
|
|
WHERE "timeCustom" >= TIMESTAMP '2009-11-10T23:00:00'
|
|
AND "timeCustom" < TIMESTAMP '2009-11-12T01:00:00' ORDER BY "timeCustom" DESC;
|
|
timeCustom | device_id | series_0 | series_1 | series_2 | series_bool
|
|
--------------------------+-----------+----------+----------+----------+-------------
|
|
Tue Nov 10 23:00:02 2009 | dev1 | 2.5 | 3 | |
|
|
Tue Nov 10 23:00:00 2009 | dev2 | 1.5 | 1 | |
|
|
Tue Nov 10 23:00:00 2009 | dev2 | 1.5 | 2 | |
|
|
(3 rows)
|
|
|
|
SET timezone = 'UTC';
|
|
SELECT date_group("timeCustom", '1 day') AS time, sum(series_0)
|
|
FROM PUBLIC."testNs" GROUP BY time ORDER BY time ASC LIMIT 2;
|
|
time | sum
|
|
--------------------------+-----
|
|
Tue Nov 10 00:00:00 2009 | 5.5
|
|
Thu Nov 12 00:00:00 2009 | 3
|
|
(2 rows)
|
|
|
|
SET timezone = 'EST';
|
|
SELECT date_group("timeCustom", '1 day') AS time, sum(series_0)
|
|
FROM PUBLIC."testNs" GROUP BY time ORDER BY time ASC LIMIT 2;
|
|
time | sum
|
|
--------------------------+-----
|
|
Mon Nov 09 19:00:00 2009 | 5.5
|
|
Wed Nov 11 19:00:00 2009 | 3
|
|
(2 rows)
|
|
|
|
------------------------------------
|
|
-- Test time conversion functions --
|
|
------------------------------------
|
|
\set ON_ERROR_STOP 0
|
|
SET timezone = 'UTC';
|
|
-- Conversion to timestamp using Postgres built-in function taking
|
|
-- double. Gives inaccurate result on Postgres <= 9.6.2. Accurate on
|
|
-- Postgres >= 9.6.3.
|
|
SELECT to_timestamp(1486480176.236538);
|
|
to_timestamp
|
|
-------------------------------------
|
|
Tue Feb 07 15:09:36.236538 2017 UTC
|
|
(1 row)
|
|
|
|
-- extension-specific version taking microsecond UNIX timestamp
|
|
SELECT _timescaledb_internal.to_timestamp(1486480176236538);
|
|
to_timestamp
|
|
-------------------------------------
|
|
Tue Feb 07 15:09:36.236538 2017 UTC
|
|
(1 row)
|
|
|
|
-- Should be the inverse of the statement above.
|
|
SELECT _timescaledb_internal.to_unix_microseconds('2017-02-07 15:09:36.236538+00');
|
|
to_unix_microseconds
|
|
----------------------
|
|
1486480176236538
|
|
(1 row)
|
|
|
|
-- In UNIX microseconds, BIGINT MAX is smaller than internal date upper bound
|
|
-- and should therefore be OK. Further, converting to the internal postgres
|
|
-- epoch cannot overflow a 64-bit INTEGER since the postgres epoch is at a
|
|
-- later date compared to the UNIX epoch, and is therefore represented by a
|
|
-- smaller number
|
|
SELECT _timescaledb_internal.to_timestamp(9223372036854775807);
|
|
to_timestamp
|
|
---------------------------------------
|
|
Sun Jan 10 04:00:54.775807 294247 UTC
|
|
(1 row)
|
|
|
|
-- Julian day zero is -210866803200000000 microseconds from UNIX epoch
|
|
SELECT _timescaledb_internal.to_timestamp(-210866803200000000);
|
|
to_timestamp
|
|
---------------------------------
|
|
Mon Nov 24 00:00:00 4714 UTC BC
|
|
(1 row)
|
|
|
|
\set VERBOSITY default
|
|
-- Going beyond Julian day zero should give out-of-range error
|
|
SELECT _timescaledb_internal.to_timestamp(-210866803200000001);
|
|
ERROR: timestamp out of range
|
|
-- Lower bound on date (should return the Julian day zero UNIX timestamp above)
|
|
SELECT _timescaledb_internal.to_unix_microseconds('4714-11-24 00:00:00+00 BC');
|
|
to_unix_microseconds
|
|
----------------------
|
|
-210866803200000000
|
|
(1 row)
|
|
|
|
-- Going beyond lower bound on date should return out-of-range
|
|
SELECT _timescaledb_internal.to_unix_microseconds('4714-11-23 23:59:59.999999+00 BC');
|
|
ERROR: timestamp out of range: "4714-11-23 23:59:59.999999+00 BC"
|
|
LINE 1: SELECT _timescaledb_internal.to_unix_microseconds('4714-11-2...
|
|
^
|
|
-- The upper bound for Postgres TIMESTAMPTZ
|
|
SELECT timestamp '294276-12-31 23:59:59.999999+00';
|
|
timestamp
|
|
-----------------------------------
|
|
Sun Dec 31 23:59:59.999999 294276
|
|
(1 row)
|
|
|
|
-- Going beyond the upper bound, should fail
|
|
SELECT timestamp '294276-12-31 23:59:59.999999+00' + interval '1 us';
|
|
ERROR: timestamp out of range
|
|
-- Cannot represent the upper bound timestamp with a UNIX microsecond timestamp
|
|
-- since the Postgres epoch is at a later date than the UNIX epoch.
|
|
SELECT _timescaledb_internal.to_unix_microseconds('294276-12-31 23:59:59.999999+00');
|
|
ERROR: timestamp out of range
|
|
-- Subtracting the difference between the two epochs (10957 days) should bring
|
|
-- us within range.
|
|
SELECT timestamp '294276-12-31 23:59:59.999999+00' - interval '10957 days';
|
|
?column?
|
|
-----------------------------------
|
|
Fri Jan 01 23:59:59.999999 294247
|
|
(1 row)
|
|
|
|
SELECT _timescaledb_internal.to_unix_microseconds('294247-01-01 23:59:59.999999');
|
|
to_unix_microseconds
|
|
----------------------
|
|
9223371331199999999
|
|
(1 row)
|
|
|
|
-- Adding one microsecond should take us out-of-range again
|
|
SELECT timestamp '294247-01-01 23:59:59.999999' + interval '1 us';
|
|
?column?
|
|
----------------------------
|
|
Sat Jan 02 00:00:00 294247
|
|
(1 row)
|
|
|
|
SELECT _timescaledb_internal.to_unix_microseconds(timestamp '294247-01-01 23:59:59.999999' + interval '1 us');
|
|
ERROR: timestamp out of range
|
|
--no time_bucketing of dates not by integer # of days
|
|
SELECT time_bucket('1 hour', DATE '2012-01-01');
|
|
ERROR: interval must not have sub-day precision
|
|
SELECT time_bucket('25 hour', DATE '2012-01-01');
|
|
ERROR: interval must be a multiple of a day
|
|
\set ON_ERROR_STOP 1
|
|
SELECT time_bucket(INTERVAL '1 day', TIMESTAMP '2011-01-02 01:01:01');
|
|
time_bucket
|
|
--------------------------
|
|
Sun Jan 02 00:00:00 2011
|
|
(1 row)
|
|
|
|
SELECT time, time_bucket(INTERVAL '2 day ', time)
|
|
FROM unnest(ARRAY[
|
|
TIMESTAMP '2011-01-01 01:01:01',
|
|
TIMESTAMP '2011-01-02 01:01:01',
|
|
TIMESTAMP '2011-01-03 01:01:01',
|
|
TIMESTAMP '2011-01-04 01:01:01'
|
|
]) AS time;
|
|
time | time_bucket
|
|
--------------------------+--------------------------
|
|
Sat Jan 01 01:01:01 2011 | Sat Jan 01 00:00:00 2011
|
|
Sun Jan 02 01:01:01 2011 | Sat Jan 01 00:00:00 2011
|
|
Mon Jan 03 01:01:01 2011 | Mon Jan 03 00:00:00 2011
|
|
Tue Jan 04 01:01:01 2011 | Mon Jan 03 00:00:00 2011
|
|
(4 rows)
|
|
|
|
SELECT int_def, time_bucket(int_def,TIMESTAMP '2011-01-02 01:01:01.111')
|
|
FROM unnest(ARRAY[
|
|
INTERVAL '1 millisecond',
|
|
INTERVAL '1 second',
|
|
INTERVAL '1 minute',
|
|
INTERVAL '1 hour',
|
|
INTERVAL '1 day',
|
|
INTERVAL '2 millisecond',
|
|
INTERVAL '2 second',
|
|
INTERVAL '2 minute',
|
|
INTERVAL '2 hour',
|
|
INTERVAL '2 day'
|
|
]) AS int_def;
|
|
int_def | time_bucket
|
|
--------------+------------------------------
|
|
@ 0.001 secs | Sun Jan 02 01:01:01.111 2011
|
|
@ 1 sec | Sun Jan 02 01:01:01 2011
|
|
@ 1 min | Sun Jan 02 01:01:00 2011
|
|
@ 1 hour | Sun Jan 02 01:00:00 2011
|
|
@ 1 day | Sun Jan 02 00:00:00 2011
|
|
@ 0.002 secs | Sun Jan 02 01:01:01.11 2011
|
|
@ 2 secs | Sun Jan 02 01:01:00 2011
|
|
@ 2 mins | Sun Jan 02 01:00:00 2011
|
|
@ 2 hours | Sun Jan 02 00:00:00 2011
|
|
@ 2 days | Sat Jan 01 00:00:00 2011
|
|
(10 rows)
|
|
|
|
\set ON_ERROR_STOP 0
|
|
SELECT time_bucket(INTERVAL '1 year',TIMESTAMP '2011-01-02 01:01:01.111');
|
|
ERROR: interval defined in terms of month, year, century etc. not supported
|
|
SELECT time_bucket(INTERVAL '1 month',TIMESTAMP '2011-01-02 01:01:01.111');
|
|
ERROR: interval defined in terms of month, year, century etc. not supported
|
|
\set ON_ERROR_STOP 1
|
|
SELECT time, time_bucket(INTERVAL '5 minute', time)
|
|
FROM unnest(ARRAY[
|
|
TIMESTAMP '1970-01-01 00:59:59.999999',
|
|
TIMESTAMP '1970-01-01 01:01:00',
|
|
TIMESTAMP '1970-01-01 01:04:59.999999',
|
|
TIMESTAMP '1970-01-01 01:05:00'
|
|
]) AS time;
|
|
time | time_bucket
|
|
---------------------------------+--------------------------
|
|
Thu Jan 01 00:59:59.999999 1970 | Thu Jan 01 00:55:00 1970
|
|
Thu Jan 01 01:01:00 1970 | Thu Jan 01 01:00:00 1970
|
|
Thu Jan 01 01:04:59.999999 1970 | Thu Jan 01 01:00:00 1970
|
|
Thu Jan 01 01:05:00 1970 | Thu Jan 01 01:05:00 1970
|
|
(4 rows)
|
|
|
|
SELECT time, time_bucket(INTERVAL '5 minute', time)
|
|
FROM unnest(ARRAY[
|
|
TIMESTAMP '2011-01-02 01:04:59.999999',
|
|
TIMESTAMP '2011-01-02 01:05:00',
|
|
TIMESTAMP '2011-01-02 01:09:59.999999',
|
|
TIMESTAMP '2011-01-02 01:10:00'
|
|
]) AS time;
|
|
time | time_bucket
|
|
---------------------------------+--------------------------
|
|
Sun Jan 02 01:04:59.999999 2011 | Sun Jan 02 01:00:00 2011
|
|
Sun Jan 02 01:05:00 2011 | Sun Jan 02 01:05:00 2011
|
|
Sun Jan 02 01:09:59.999999 2011 | Sun Jan 02 01:05:00 2011
|
|
Sun Jan 02 01:10:00 2011 | Sun Jan 02 01:10:00 2011
|
|
(4 rows)
|
|
|
|
--offset with interval
|
|
SELECT time, time_bucket(INTERVAL '5 minute', time , INTERVAL '2 minutes')
|
|
FROM unnest(ARRAY[
|
|
TIMESTAMP '2011-01-02 01:01:59.999999',
|
|
TIMESTAMP '2011-01-02 01:02:00',
|
|
TIMESTAMP '2011-01-02 01:06:59.999999',
|
|
TIMESTAMP '2011-01-02 01:07:00'
|
|
]) AS time;
|
|
time | time_bucket
|
|
---------------------------------+--------------------------
|
|
Sun Jan 02 01:01:59.999999 2011 | Sun Jan 02 00:57:00 2011
|
|
Sun Jan 02 01:02:00 2011 | Sun Jan 02 01:02:00 2011
|
|
Sun Jan 02 01:06:59.999999 2011 | Sun Jan 02 01:02:00 2011
|
|
Sun Jan 02 01:07:00 2011 | Sun Jan 02 01:07:00 2011
|
|
(4 rows)
|
|
|
|
SELECT time, time_bucket(INTERVAL '5 minute', time , - INTERVAL '2 minutes')
|
|
FROM unnest(ARRAY[
|
|
TIMESTAMP '2011-01-02 01:02:59.999999',
|
|
TIMESTAMP '2011-01-02 01:03:00',
|
|
TIMESTAMP '2011-01-02 01:07:59.999999',
|
|
TIMESTAMP '2011-01-02 01:08:00'
|
|
]) AS time;
|
|
time | time_bucket
|
|
---------------------------------+--------------------------
|
|
Sun Jan 02 01:02:59.999999 2011 | Sun Jan 02 00:58:00 2011
|
|
Sun Jan 02 01:03:00 2011 | Sun Jan 02 01:03:00 2011
|
|
Sun Jan 02 01:07:59.999999 2011 | Sun Jan 02 01:03:00 2011
|
|
Sun Jan 02 01:08:00 2011 | Sun Jan 02 01:08:00 2011
|
|
(4 rows)
|
|
|
|
--example to align with an origin
|
|
SELECT time, time_bucket(INTERVAL '5 minute', time - (TIMESTAMP '2011-01-02 00:02:00' - TIMESTAMP 'epoch')) + (TIMESTAMP '2011-01-02 00:02:00'-TIMESTAMP 'epoch')
|
|
FROM unnest(ARRAY[
|
|
TIMESTAMP '2011-01-02 01:01:59.999999',
|
|
TIMESTAMP '2011-01-02 01:02:00',
|
|
TIMESTAMP '2011-01-02 01:06:59.999999',
|
|
TIMESTAMP '2011-01-02 01:07:00'
|
|
]) AS time;
|
|
time | ?column?
|
|
---------------------------------+--------------------------
|
|
Sun Jan 02 01:01:59.999999 2011 | Sun Jan 02 00:57:00 2011
|
|
Sun Jan 02 01:02:00 2011 | Sun Jan 02 01:02:00 2011
|
|
Sun Jan 02 01:06:59.999999 2011 | Sun Jan 02 01:02:00 2011
|
|
Sun Jan 02 01:07:00 2011 | Sun Jan 02 01:07:00 2011
|
|
(4 rows)
|
|
|
|
--rounding version
|
|
SELECT time, time_bucket(INTERVAL '5 minute', time , - INTERVAL '2.5 minutes') + INTERVAL '2 minutes 30 seconds'
|
|
FROM unnest(ARRAY[
|
|
TIMESTAMP '2011-01-02 01:05:01',
|
|
TIMESTAMP '2011-01-02 01:07:29',
|
|
TIMESTAMP '2011-01-02 01:02:30',
|
|
TIMESTAMP '2011-01-02 01:07:30',
|
|
TIMESTAMP '2011-01-02 01:02:29'
|
|
]) AS time;
|
|
time | ?column?
|
|
--------------------------+--------------------------
|
|
Sun Jan 02 01:05:01 2011 | Sun Jan 02 01:05:00 2011
|
|
Sun Jan 02 01:07:29 2011 | Sun Jan 02 01:05:00 2011
|
|
Sun Jan 02 01:02:30 2011 | Sun Jan 02 01:05:00 2011
|
|
Sun Jan 02 01:07:30 2011 | Sun Jan 02 01:10:00 2011
|
|
Sun Jan 02 01:02:29 2011 | Sun Jan 02 01:00:00 2011
|
|
(5 rows)
|
|
|
|
--time_bucket with timezone should mimick date_trunc
|
|
SET timezone TO 'UTC';
|
|
SELECT time, time_bucket(INTERVAL '1 hour', time), date_trunc('hour', time)
|
|
FROM unnest(ARRAY[
|
|
TIMESTAMP WITH TIME ZONE '2011-01-02 01:01:01',
|
|
TIMESTAMP WITH TIME ZONE '2011-01-02 01:01:01+01',
|
|
TIMESTAMP WITH TIME ZONE '2011-01-02 01:01:01+02'
|
|
]) AS time;
|
|
time | time_bucket | date_trunc
|
|
------------------------------+------------------------------+------------------------------
|
|
Sun Jan 02 01:01:01 2011 UTC | Sun Jan 02 01:00:00 2011 UTC | Sun Jan 02 01:00:00 2011 UTC
|
|
Sun Jan 02 00:01:01 2011 UTC | Sun Jan 02 00:00:00 2011 UTC | Sun Jan 02 00:00:00 2011 UTC
|
|
Sat Jan 01 23:01:01 2011 UTC | Sat Jan 01 23:00:00 2011 UTC | Sat Jan 01 23:00:00 2011 UTC
|
|
(3 rows)
|
|
|
|
SELECT time, time_bucket(INTERVAL '1 day', time), date_trunc('day', time)
|
|
FROM unnest(ARRAY[
|
|
TIMESTAMP WITH TIME ZONE '2011-01-02 01:01:01',
|
|
TIMESTAMP WITH TIME ZONE '2011-01-02 01:01:01+01',
|
|
TIMESTAMP WITH TIME ZONE '2011-01-02 01:01:01+02'
|
|
]) AS time;
|
|
time | time_bucket | date_trunc
|
|
------------------------------+------------------------------+------------------------------
|
|
Sun Jan 02 01:01:01 2011 UTC | Sun Jan 02 00:00:00 2011 UTC | Sun Jan 02 00:00:00 2011 UTC
|
|
Sun Jan 02 00:01:01 2011 UTC | Sun Jan 02 00:00:00 2011 UTC | Sun Jan 02 00:00:00 2011 UTC
|
|
Sat Jan 01 23:01:01 2011 UTC | Sat Jan 01 00:00:00 2011 UTC | Sat Jan 01 00:00:00 2011 UTC
|
|
(3 rows)
|
|
|
|
--what happens with a local tz
|
|
SET timezone TO 'America/New_York';
|
|
SELECT time, time_bucket(INTERVAL '1 hour', time), date_trunc('hour', time)
|
|
FROM unnest(ARRAY[
|
|
TIMESTAMP WITH TIME ZONE '2011-01-02 01:01:01',
|
|
TIMESTAMP WITH TIME ZONE '2011-01-02 01:01:01+01',
|
|
TIMESTAMP WITH TIME ZONE '2011-01-02 01:01:01+02'
|
|
]) AS time;
|
|
time | time_bucket | date_trunc
|
|
------------------------------+------------------------------+------------------------------
|
|
Sun Jan 02 01:01:01 2011 EST | Sun Jan 02 01:00:00 2011 EST | Sun Jan 02 01:00:00 2011 EST
|
|
Sat Jan 01 19:01:01 2011 EST | Sat Jan 01 19:00:00 2011 EST | Sat Jan 01 19:00:00 2011 EST
|
|
Sat Jan 01 18:01:01 2011 EST | Sat Jan 01 18:00:00 2011 EST | Sat Jan 01 18:00:00 2011 EST
|
|
(3 rows)
|
|
|
|
--Note the timestamp tz input is aligned with UTC day /not/ local day. different than date_trunc.
|
|
SELECT time, time_bucket(INTERVAL '1 day', time), date_trunc('day', time)
|
|
FROM unnest(ARRAY[
|
|
TIMESTAMP WITH TIME ZONE '2011-01-02 01:01:01',
|
|
TIMESTAMP WITH TIME ZONE '2011-01-03 01:01:01+01',
|
|
TIMESTAMP WITH TIME ZONE '2011-01-04 01:01:01+02'
|
|
]) AS time;
|
|
time | time_bucket | date_trunc
|
|
------------------------------+------------------------------+------------------------------
|
|
Sun Jan 02 01:01:01 2011 EST | Sat Jan 01 19:00:00 2011 EST | Sun Jan 02 00:00:00 2011 EST
|
|
Sun Jan 02 19:01:01 2011 EST | Sun Jan 02 19:00:00 2011 EST | Sun Jan 02 00:00:00 2011 EST
|
|
Mon Jan 03 18:01:01 2011 EST | Sun Jan 02 19:00:00 2011 EST | Mon Jan 03 00:00:00 2011 EST
|
|
(3 rows)
|
|
|
|
--can force local bucketing with simple cast.
|
|
SELECT time, time_bucket(INTERVAL '1 day', time::timestamp), date_trunc('day', time)
|
|
FROM unnest(ARRAY[
|
|
TIMESTAMP WITH TIME ZONE '2011-01-02 01:01:01',
|
|
TIMESTAMP WITH TIME ZONE '2011-01-03 01:01:01+01',
|
|
TIMESTAMP WITH TIME ZONE '2011-01-04 01:01:01+02'
|
|
]) AS time;
|
|
time | time_bucket | date_trunc
|
|
------------------------------+--------------------------+------------------------------
|
|
Sun Jan 02 01:01:01 2011 EST | Sun Jan 02 00:00:00 2011 | Sun Jan 02 00:00:00 2011 EST
|
|
Sun Jan 02 19:01:01 2011 EST | Sun Jan 02 00:00:00 2011 | Sun Jan 02 00:00:00 2011 EST
|
|
Mon Jan 03 18:01:01 2011 EST | Mon Jan 03 00:00:00 2011 | Mon Jan 03 00:00:00 2011 EST
|
|
(3 rows)
|
|
|
|
--can also use interval to correct
|
|
SELECT time, time_bucket(INTERVAL '1 day', time, -INTERVAL '19 hours'), date_trunc('day', time)
|
|
FROM unnest(ARRAY[
|
|
TIMESTAMP WITH TIME ZONE '2011-01-02 01:01:01',
|
|
TIMESTAMP WITH TIME ZONE '2011-01-03 01:01:01+01',
|
|
TIMESTAMP WITH TIME ZONE '2011-01-04 01:01:01+02'
|
|
]) AS time;
|
|
time | time_bucket | date_trunc
|
|
------------------------------+------------------------------+------------------------------
|
|
Sun Jan 02 01:01:01 2011 EST | Sun Jan 02 00:00:00 2011 EST | Sun Jan 02 00:00:00 2011 EST
|
|
Sun Jan 02 19:01:01 2011 EST | Sun Jan 02 00:00:00 2011 EST | Sun Jan 02 00:00:00 2011 EST
|
|
Mon Jan 03 18:01:01 2011 EST | Mon Jan 03 00:00:00 2011 EST | Mon Jan 03 00:00:00 2011 EST
|
|
(3 rows)
|
|
|
|
--dst: same local hour bucketed as two different hours.
|
|
SELECT time, time_bucket(INTERVAL '1 hour', time), date_trunc('hour', time)
|
|
FROM unnest(ARRAY[
|
|
TIMESTAMP WITH TIME ZONE '2017-11-05 12:05:00+07',
|
|
TIMESTAMP WITH TIME ZONE '2017-11-05 13:05:00+07'
|
|
]) AS time;
|
|
time | time_bucket | date_trunc
|
|
------------------------------+------------------------------+------------------------------
|
|
Sun Nov 05 01:05:00 2017 EDT | Sun Nov 05 01:00:00 2017 EDT | Sun Nov 05 01:00:00 2017 EDT
|
|
Sun Nov 05 01:05:00 2017 EST | Sun Nov 05 01:00:00 2017 EST | Sun Nov 05 01:00:00 2017 EST
|
|
(2 rows)
|
|
|
|
--local alignment changes when bucketing by UTC across dst boundary
|
|
SELECT time, time_bucket(INTERVAL '2 hour', time)
|
|
FROM unnest(ARRAY[
|
|
TIMESTAMP WITH TIME ZONE '2017-11-05 10:05:00+07',
|
|
TIMESTAMP WITH TIME ZONE '2017-11-05 12:05:00+07',
|
|
TIMESTAMP WITH TIME ZONE '2017-11-05 13:05:00+07',
|
|
TIMESTAMP WITH TIME ZONE '2017-11-05 15:05:00+07'
|
|
]) AS time;
|
|
time | time_bucket
|
|
------------------------------+------------------------------
|
|
Sat Nov 04 23:05:00 2017 EDT | Sat Nov 04 22:00:00 2017 EDT
|
|
Sun Nov 05 01:05:00 2017 EDT | Sun Nov 05 00:00:00 2017 EDT
|
|
Sun Nov 05 01:05:00 2017 EST | Sun Nov 05 01:00:00 2017 EST
|
|
Sun Nov 05 03:05:00 2017 EST | Sun Nov 05 03:00:00 2017 EST
|
|
(4 rows)
|
|
|
|
--local alignment is preserved when bucketing by local time across DST boundary.
|
|
SELECT time, time_bucket(INTERVAL '2 hour', time::timestamp)
|
|
FROM unnest(ARRAY[
|
|
TIMESTAMP WITH TIME ZONE '2017-11-05 10:05:00+07',
|
|
TIMESTAMP WITH TIME ZONE '2017-11-05 12:05:00+07',
|
|
TIMESTAMP WITH TIME ZONE '2017-11-05 13:05:00+07',
|
|
TIMESTAMP WITH TIME ZONE '2017-11-05 15:05:00+07'
|
|
]) AS time;
|
|
time | time_bucket
|
|
------------------------------+--------------------------
|
|
Sat Nov 04 23:05:00 2017 EDT | Sat Nov 04 22:00:00 2017
|
|
Sun Nov 05 01:05:00 2017 EDT | Sun Nov 05 00:00:00 2017
|
|
Sun Nov 05 01:05:00 2017 EST | Sun Nov 05 00:00:00 2017
|
|
Sun Nov 05 03:05:00 2017 EST | Sun Nov 05 02:00:00 2017
|
|
(4 rows)
|
|
|
|
SELECT time, time_bucket(10, time)
|
|
FROM unnest(ARRAY[
|
|
'99',
|
|
'100',
|
|
'109',
|
|
'110'
|
|
]::int[]) AS time;
|
|
time | time_bucket
|
|
------+-------------
|
|
99 | 90
|
|
100 | 100
|
|
109 | 100
|
|
110 | 110
|
|
(4 rows)
|
|
|
|
SELECT time, time_bucket(10, time,2)
|
|
FROM unnest(ARRAY[
|
|
'101',
|
|
'102',
|
|
'111',
|
|
'112'
|
|
]::int[]) AS time;
|
|
time | time_bucket
|
|
------+-------------
|
|
101 | 92
|
|
102 | 102
|
|
111 | 102
|
|
112 | 112
|
|
(4 rows)
|
|
|
|
SELECT time, time_bucket(10, time, -2)
|
|
FROM unnest(ARRAY[
|
|
'97',
|
|
'98',
|
|
'107',
|
|
'108'
|
|
]::int[]) AS time;
|
|
time | time_bucket
|
|
------+-------------
|
|
97 | 88
|
|
98 | 98
|
|
107 | 98
|
|
108 | 108
|
|
(4 rows)
|
|
|
|
SELECT time, time_bucket(INTERVAL '1 day', time::date)
|
|
FROM unnest(ARRAY[
|
|
date '2017-11-05',
|
|
date '2017-11-06'
|
|
]) AS time;
|
|
time | time_bucket
|
|
------------+-------------
|
|
11-05-2017 | 11-05-2017
|
|
11-06-2017 | 11-06-2017
|
|
(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',
|
|
date '2017-11-08',
|
|
date '2017-11-09'
|
|
]) AS time;
|
|
time | time_bucket
|
|
------------+-------------
|
|
11-04-2017 | 11-01-2017
|
|
11-05-2017 | 11-05-2017
|
|
11-08-2017 | 11-05-2017
|
|
11-09-2017 | 11-09-2017
|
|
(4 rows)
|
|
|
|
-------------------------------------
|
|
--- Test time input functions --
|
|
-------------------------------------
|
|
\c single :ROLE_SUPERUSER
|
|
CREATE OR REPLACE FUNCTION test.interval_to_internal(coltype REGTYPE, value ANYELEMENT = NULL::BIGINT) RETURNS BIGINT
|
|
AS :MODULE_PATHNAME, 'dimension_interval_to_internal_test' LANGUAGE C VOLATILE;
|
|
\c single :ROLE_DEFAULT_PERM_USER
|
|
SELECT test.interval_to_internal('TIMESTAMP'::regtype, INTERVAL '1 day');
|
|
interval_to_internal
|
|
----------------------
|
|
86400000000
|
|
(1 row)
|
|
|
|
SELECT test.interval_to_internal('TIMESTAMP'::regtype, 86400000000);
|
|
interval_to_internal
|
|
----------------------
|
|
86400000000
|
|
(1 row)
|
|
|
|
---should give warning
|
|
SELECT test.interval_to_internal('TIMESTAMP'::regtype, 86400);
|
|
WARNING: unexpected interval: smaller than one second
|
|
HINT: The interval is specified in microseconds
|
|
interval_to_internal
|
|
----------------------
|
|
86400
|
|
(1 row)
|
|
|
|
SELECT test.interval_to_internal('TIMESTAMP'::regtype);
|
|
interval_to_internal
|
|
----------------------
|
|
604800000000
|
|
(1 row)
|
|
|
|
SELECT test.interval_to_internal('BIGINT'::regtype, 2147483649::bigint);
|
|
interval_to_internal
|
|
----------------------
|
|
2147483649
|
|
(1 row)
|
|
|
|
\set VERBOSITY terse
|
|
\set ON_ERROR_STOP 0
|
|
SELECT test.interval_to_internal('INT'::regtype);
|
|
ERROR: integer dimensions require an explicit interval
|
|
SELECT test.interval_to_internal('INT'::regtype, 2147483649::bigint);
|
|
ERROR: invalid interval: must be between 1 and 2147483647
|
|
SELECT test.interval_to_internal('SMALLINT'::regtype, 32768::bigint);
|
|
ERROR: invalid interval: must be between 1 and 32767
|
|
SELECT test.interval_to_internal('TEXT'::regtype, 32768::bigint);
|
|
ERROR: invalid dimension type: "testcol" must be an integer, date or timestamp
|
|
SELECT test.interval_to_internal('INT'::regtype, INTERVAL '1 day');
|
|
ERROR: invalid interval: must be an integer type for integer dimensions
|
|
\set ON_ERROR_STOP 1
|