1
0
mirror of https://github.com/timescale/timescaledb.git synced 2025-05-15 10:11:29 +08:00
Rob Kiefer 7e9bf25ce6 Change default chunk size to one week
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.
2018-08-08 12:01:15 -04:00

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