Fix continuous aggregate materialization timezone handling

For hypertables with a TIMESTAMP column materialization would not
honor the local timezone when determining the range for materialization
and instead treat times as UTC.
This commit is contained in:
Sven Klemm 2020-03-11 01:40:33 +01:00 committed by Sven Klemm
parent 656bd3f6cc
commit c61e799d1f
3 changed files with 103 additions and 0 deletions

View File

@ -374,6 +374,14 @@ ts_get_now_internal(Dimension *open_dim)
#else
Datum now_datum = TimestampTzGetDatum(GetCurrentTimestamp());
#endif
/*
* If the type of the partitioning column is TIMESTAMP or DATE
* we need to adjust the return value for the local timezone.
*/
if (dim_post_part_type == TIMESTAMPOID || dim_post_part_type == DATEOID)
now_datum = DirectFunctionCall1(timestamptz_timestamp, now_datum);
return ts_time_value_to_internal(now_datum, TIMESTAMPTZOID);
}
}

View File

@ -1439,3 +1439,57 @@ SELECT view_name, refresh_lag, max_interval_per_job
max_mat_view_date | @ 7 days ago | @ 140 days
(4 rows)
-- test timezone is respected when materializing cagg with TIMESTAMP time column
RESET timescaledb.current_timestamp_mock;
RESET client_min_messages;
SET SESSION timezone TO 'GMT+5';
CREATE TABLE timezone_test(time timestamp NOT NULL);
SELECT table_name FROM create_hypertable('timezone_test','time');
table_name
---------------
timezone_test
(1 row)
INSERT INTO timezone_test VALUES (now() - '30m'::interval), (now()), (now() + '30m'::interval);
CREATE VIEW timezone_test_summary
WITH (timescaledb.continuous)
AS SELECT time_bucket('5m', time)
FROM timezone_test
GROUP BY 1;
REFRESH MATERIALIZED VIEW timezone_test_summary;
-- this must return 1 as only 1 row is in the materialization interval
SELECT count(*) FROM timezone_test_summary;
count
-------
1
(1 row)
DROP TABLE timezone_test CASCADE;
NOTICE: drop cascades to 2 other objects
NOTICE: drop cascades to table _timescaledb_internal._hyper_21_42_chunk
-- repeat test with timezone with negative offset
SET SESSION timezone TO 'GMT-5';
CREATE TABLE timezone_test(time timestamp NOT NULL);
SELECT table_name FROM create_hypertable('timezone_test','time');
table_name
---------------
timezone_test
(1 row)
INSERT INTO timezone_test VALUES (now() - '30m'::interval), (now()), (now() + '30m'::interval);
CREATE VIEW timezone_test_summary
WITH (timescaledb.continuous)
AS SELECT time_bucket('5m', time)
FROM timezone_test
GROUP BY 1;
REFRESH MATERIALIZED VIEW timezone_test_summary;
-- this must return 1 as only 1 row is in the materialization interval
SELECT count(*) FROM timezone_test_summary;
count
-------
1
(1 row)
DROP TABLE timezone_test CASCADE;
NOTICE: drop cascades to 2 other objects
NOTICE: drop cascades to table _timescaledb_internal._hyper_23_44_chunk

View File

@ -655,3 +655,44 @@ SELECT view_name, completed_threshold, invalidation_threshold, job_id, job_statu
SELECT view_name, refresh_lag, max_interval_per_job
FROM timescaledb_information.continuous_aggregates ORDER BY 1;
-- test timezone is respected when materializing cagg with TIMESTAMP time column
RESET timescaledb.current_timestamp_mock;
RESET client_min_messages;
SET SESSION timezone TO 'GMT+5';
CREATE TABLE timezone_test(time timestamp NOT NULL);
SELECT table_name FROM create_hypertable('timezone_test','time');
INSERT INTO timezone_test VALUES (now() - '30m'::interval), (now()), (now() + '30m'::interval);
CREATE VIEW timezone_test_summary
WITH (timescaledb.continuous)
AS SELECT time_bucket('5m', time)
FROM timezone_test
GROUP BY 1;
REFRESH MATERIALIZED VIEW timezone_test_summary;
-- this must return 1 as only 1 row is in the materialization interval
SELECT count(*) FROM timezone_test_summary;
DROP TABLE timezone_test CASCADE;
-- repeat test with timezone with negative offset
SET SESSION timezone TO 'GMT-5';
CREATE TABLE timezone_test(time timestamp NOT NULL);
SELECT table_name FROM create_hypertable('timezone_test','time');
INSERT INTO timezone_test VALUES (now() - '30m'::interval), (now()), (now() + '30m'::interval);
CREATE VIEW timezone_test_summary
WITH (timescaledb.continuous)
AS SELECT time_bucket('5m', time)
FROM timezone_test
GROUP BY 1;
REFRESH MATERIALIZED VIEW timezone_test_summary;
-- this must return 1 as only 1 row is in the materialization interval
SELECT count(*) FROM timezone_test_summary;
DROP TABLE timezone_test CASCADE;