timescaledb/test/sql/timestamp_limits.sql
Erik Nordström c5a202476e Fix timestamp overflow in time_bucket optimization
An optimization for `time_bucket` transforms expressions of the form
`time_bucket(10, time) < 100` to `time < 100 + 10` in order to do
chunk exclusion and make better use of indexes on the time
column. However, since one bucket is added to the timestamp when doing
this transformation, the timestamp can overflow.

While a check for such overflows already exists, it uses `+Infinity`
(INT64_MAX/DT_NOEND) as the upper bound instead of the actual end of
the valid timestamp range. A further complication arises because
TimescaleDB internally converts timestamps to UNIX epoch time, thus
losing a little bit of the valid timestamp range in the process. Dates
are further restricted by the fact that they are internally first
converted to timestamps (thus limited by the timestamp range) and then
converted to UNIX epoch.

This change fixes the overflow issue by only applying the
transformation if the resulting timestamps or dates stay within the
valid (TimescaleDB-specific) ranges.

A test has also been added to show the valid timestamp and date
ranges, both PostgreSQL and TimescaleDB-specific ones.
2020-08-27 19:16:24 +02:00

42 lines
1.8 KiB
SQL

-- This file and its contents are licensed under the Apache License 2.0.
-- Please see the included NOTICE for copyright information and
-- LICENSE-APACHE for a copy of the license.
\c :TEST_DBNAME :ROLE_SUPERUSER
CREATE OR REPLACE FUNCTION test.min_pg_timestamptz() RETURNS TIMESTAMPTZ
AS :MODULE_PATHNAME, 'ts_timestamptz_pg_min' LANGUAGE C VOLATILE;
CREATE OR REPLACE FUNCTION test.end_pg_timestamptz() RETURNS TIMESTAMPTZ
AS :MODULE_PATHNAME, 'ts_timestamptz_pg_end' LANGUAGE C VOLATILE;
CREATE OR REPLACE FUNCTION test.min_ts_timestamptz() RETURNS TIMESTAMPTZ
AS :MODULE_PATHNAME, 'ts_timestamptz_min' LANGUAGE C VOLATILE;
CREATE OR REPLACE FUNCTION test.end_ts_timestamptz() RETURNS TIMESTAMPTZ
AS :MODULE_PATHNAME, 'ts_timestamptz_end' LANGUAGE C VOLATILE;
CREATE OR REPLACE FUNCTION test.min_pg_date() RETURNS DATE
AS :MODULE_PATHNAME, 'ts_date_pg_min' LANGUAGE C VOLATILE;
CREATE OR REPLACE FUNCTION test.end_pg_date() RETURNS DATE
AS :MODULE_PATHNAME, 'ts_date_pg_end' LANGUAGE C VOLATILE;
CREATE OR REPLACE FUNCTION test.min_ts_date() RETURNS DATE
AS :MODULE_PATHNAME, 'ts_date_min' LANGUAGE C VOLATILE;
CREATE OR REPLACE FUNCTION test.end_ts_date() RETURNS DATE
AS :MODULE_PATHNAME, 'ts_date_end' LANGUAGE C VOLATILE;
SET ROLE :ROLE_DEFAULT_PERM_USER;
--show PG and TimescaleDB-specific time boundaries. Note that we
--internally convert to UNIX epoch, which restricts the range of
--supported timestamps.
SET datestyle TO 'ISO,YMD';
SELECT test.min_pg_timestamptz(), test.end_pg_timestamptz(), test.min_ts_timestamptz(), test.end_ts_timestamptz();
--TimescaleDB-specific dates should be consistent with timestamps
--since we internally first convert dates to timestamps and then to
--UNIX epoch.
SELECT test.min_pg_date(), test.end_pg_date(), test.min_ts_date(), test.end_ts_date();
RESET datestyle;