mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-15 01:53:41 +08:00
Fix next_start calculation for fixed schedules
This patch fixes several issues with next_start calculation. - Previously, the offset was added twice in some cases. This is fixed by this patch. - Additionally, schedule intervals with month components were not handled correctly. Internally, time_bucket with origin is used to calculate the next start. However, in the case of month intervals, the timestamp calculated for a bucket is always aligned on the first day of the month, regardless of origin. Therefore, previously the result was aligned with origin by adding the difference between origin and its respective time bucket. This difference was computed as a fixed length interval in terms of days and time. That computation led to incorrect computation of next start occasionally, for example when a job should be executed on the last day of a month. That is fixed by adding an appropriate interval of months to initial_start and letting Postgres handle this computation properly. Fixes #5216
This commit is contained in:
parent
756ef68d0a
commit
348796f9d9
@ -17,6 +17,7 @@ accidentally triggering the load of a previous DB version.**
|
||||
* #5218 Add role-level security to job error log
|
||||
* #5214 Fix use of prepared statement in async module
|
||||
* #5290 Compression can't be enabled on continuous aggregates when segmentby/orderby columns need quotation
|
||||
* #5239 Fix next_start calculation for fixed schedules
|
||||
|
||||
## 2.9.3 (2023-02-03)
|
||||
|
||||
@ -35,6 +36,7 @@ upgrade as soon as possible.
|
||||
* @ssmoss for reporting issues on continuous aggregates
|
||||
* @jaskij for reporting the compliation issue that occurred with clang
|
||||
|
||||
|
||||
## 2.9.2 (2023-01-26)
|
||||
|
||||
This release contains bug fixes since the 2.9.1 release.
|
||||
|
@ -170,61 +170,105 @@ typedef struct
|
||||
} JobResultCtx;
|
||||
|
||||
/*
|
||||
* time_bucket(schedule_interval, finish_time, origin => initial_start)
|
||||
* logic is the following
|
||||
* Ideally we would return
|
||||
* time_bucket(schedule_interval, finish_time, origin => initial_start, timezone).
|
||||
* That is what we return when the schedule interval does not have month components.
|
||||
* However, when there is a month component in the schedule interval,
|
||||
* then supplying the origin in time_bucket
|
||||
* does not work and the returned bucket is aligned on the start of the month.
|
||||
* In those cases, we only have month components. So we compute the difference in
|
||||
* months between the initial_start's timebucket and the finish time's bucket.
|
||||
*/
|
||||
static TimestampTz
|
||||
get_next_scheduled_execution_slot(BgwJob *job, TimestampTz finish_time)
|
||||
{
|
||||
Assert(job->fd.fixed_schedule == true);
|
||||
Datum timebucket_fini, result, offset;
|
||||
Datum schedint_datum = IntervalPGetDatum(&job->fd.schedule_interval);
|
||||
Datum timebucket_fini, timebucket_init, result;
|
||||
|
||||
if (job->fd.timezone == NULL)
|
||||
Interval one_month = {
|
||||
.day = 0,
|
||||
.time = 0,
|
||||
.month = 1,
|
||||
};
|
||||
|
||||
if (job->fd.schedule_interval.month > 0)
|
||||
{
|
||||
offset = DirectFunctionCall2(ts_timestamptz_bucket,
|
||||
schedint_datum,
|
||||
TimestampTzGetDatum(job->fd.initial_start));
|
||||
if (job->fd.timezone == NULL)
|
||||
{
|
||||
timebucket_init = DirectFunctionCall2(ts_timestamptz_bucket,
|
||||
schedint_datum,
|
||||
TimestampTzGetDatum(job->fd.initial_start));
|
||||
timebucket_fini = DirectFunctionCall2(ts_timestamptz_bucket,
|
||||
schedint_datum,
|
||||
TimestampTzGetDatum(finish_time));
|
||||
}
|
||||
else
|
||||
{
|
||||
char *tz = text_to_cstring(job->fd.timezone);
|
||||
timebucket_fini = DirectFunctionCall3(ts_timestamptz_timezone_bucket,
|
||||
schedint_datum,
|
||||
TimestampTzGetDatum(finish_time),
|
||||
CStringGetTextDatum(tz));
|
||||
|
||||
timebucket_fini = DirectFunctionCall3(ts_timestamptz_bucket,
|
||||
schedint_datum,
|
||||
TimestampTzGetDatum(finish_time),
|
||||
TimestampTzGetDatum(job->fd.initial_start));
|
||||
/* always the next time_bucket */
|
||||
result = DirectFunctionCall2(timestamptz_pl_interval, timebucket_fini, schedint_datum);
|
||||
timebucket_init = DirectFunctionCall3(ts_timestamptz_timezone_bucket,
|
||||
schedint_datum,
|
||||
TimestampTzGetDatum(job->fd.initial_start),
|
||||
CStringGetTextDatum(tz));
|
||||
}
|
||||
/* always the next bucket */
|
||||
timebucket_fini =
|
||||
DirectFunctionCall2(timestamptz_pl_interval, timebucket_fini, schedint_datum);
|
||||
/* get the number of months between them */
|
||||
Datum year_init =
|
||||
DirectFunctionCall2(timestamptz_part, CStringGetTextDatum("year"), timebucket_init);
|
||||
Datum year_fini =
|
||||
DirectFunctionCall2(timestamptz_part, CStringGetTextDatum("year"), timebucket_fini);
|
||||
|
||||
Datum month_init =
|
||||
DirectFunctionCall2(timestamptz_part, CStringGetTextDatum("month"), timebucket_init);
|
||||
Datum month_fini =
|
||||
DirectFunctionCall2(timestamptz_part, CStringGetTextDatum("month"), timebucket_fini);
|
||||
|
||||
/* convert everything to months */
|
||||
float8 month_diff = DatumGetFloat8(year_fini) * 12 + DatumGetFloat8(month_fini) -
|
||||
(DatumGetFloat8(year_init) * 12 + DatumGetFloat8(month_init));
|
||||
|
||||
Datum months_to_add = DirectFunctionCall2(interval_mul,
|
||||
IntervalPGetDatum(&one_month),
|
||||
Float8GetDatum(month_diff));
|
||||
|
||||
result = DirectFunctionCall2(timestamptz_pl_interval,
|
||||
TimestampTzGetDatum(job->fd.initial_start),
|
||||
months_to_add);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *tz = text_to_cstring(job->fd.timezone);
|
||||
timebucket_fini = DirectFunctionCall4(ts_timestamptz_timezone_bucket,
|
||||
schedint_datum,
|
||||
TimestampTzGetDatum(finish_time),
|
||||
CStringGetTextDatum(tz),
|
||||
TimestampTzGetDatum(job->fd.initial_start));
|
||||
/* always the next time_bucket */
|
||||
result = DirectFunctionCall2(timestamptz_pl_interval, timebucket_fini, schedint_datum);
|
||||
|
||||
offset = DirectFunctionCall3(ts_timestamptz_timezone_bucket,
|
||||
schedint_datum,
|
||||
TimestampTzGetDatum(job->fd.initial_start),
|
||||
CStringGetTextDatum(tz));
|
||||
if (job->fd.timezone == NULL)
|
||||
{
|
||||
/* it is safe to use the origin in time_bucket calculation */
|
||||
timebucket_fini = DirectFunctionCall3(ts_timestamptz_bucket,
|
||||
schedint_datum,
|
||||
TimestampTzGetDatum(finish_time),
|
||||
TimestampTzGetDatum(job->fd.initial_start));
|
||||
result = timebucket_fini;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *tz = text_to_cstring(job->fd.timezone);
|
||||
timebucket_fini = DirectFunctionCall4(ts_timestamptz_timezone_bucket,
|
||||
schedint_datum,
|
||||
TimestampTzGetDatum(finish_time),
|
||||
CStringGetTextDatum(tz),
|
||||
TimestampTzGetDatum(job->fd.initial_start));
|
||||
result = timebucket_fini;
|
||||
}
|
||||
}
|
||||
|
||||
offset = DirectFunctionCall2(timestamp_mi, TimestampTzGetDatum(job->fd.initial_start), offset);
|
||||
/* if we have a month component, the origin doesn't work so we must manually
|
||||
include the offset */
|
||||
if (job->fd.schedule_interval.month)
|
||||
{
|
||||
result = DirectFunctionCall2(timestamptz_pl_interval, result, offset);
|
||||
}
|
||||
/*
|
||||
* adding the schedule interval above to get the next bucket might still not hit
|
||||
* the next bucket if we are crossing DST. So we can end up with a next_start value
|
||||
* that is actually less than the finish time of the job. Hence, we have to make sure
|
||||
* the next scheduled slot we compute is in the future and not in the past
|
||||
*/
|
||||
while (DatumGetTimestampTz(result) <= finish_time)
|
||||
{
|
||||
result = DirectFunctionCall2(timestamptz_pl_interval, result, schedint_datum);
|
||||
|
||||
}
|
||||
return DatumGetTimestampTz(result);
|
||||
}
|
||||
|
||||
|
@ -67,55 +67,89 @@ ts_test_next_scheduled_execution_slot(PG_FUNCTION_ARGS)
|
||||
TimestampTz initial_start = PG_GETARG_TIMESTAMPTZ(2);
|
||||
text *timezone = PG_ARGISNULL(3) ? NULL : PG_GETARG_TEXT_PP(3);
|
||||
|
||||
Datum timebucket_fini, result, offset;
|
||||
Datum timebucket_fini, timebucket_init, result;
|
||||
Datum schedint_datum = IntervalPGetDatum(schedule_interval);
|
||||
Interval one_month = {
|
||||
.day = 0,
|
||||
.time = 0,
|
||||
.month = 1,
|
||||
};
|
||||
|
||||
if (timezone == NULL)
|
||||
if (schedule_interval->month > 0)
|
||||
{
|
||||
offset = DirectFunctionCall2(ts_timestamptz_bucket,
|
||||
schedint_datum,
|
||||
TimestampTzGetDatum(initial_start));
|
||||
if (timezone == NULL)
|
||||
{
|
||||
timebucket_init = DirectFunctionCall2(ts_timestamptz_bucket,
|
||||
schedint_datum,
|
||||
TimestampTzGetDatum(initial_start));
|
||||
timebucket_fini = DirectFunctionCall2(ts_timestamptz_bucket,
|
||||
schedint_datum,
|
||||
TimestampTzGetDatum(finish_time));
|
||||
}
|
||||
else
|
||||
{
|
||||
char *tz = text_to_cstring(timezone);
|
||||
timebucket_fini = DirectFunctionCall3(ts_timestamptz_timezone_bucket,
|
||||
schedint_datum,
|
||||
TimestampTzGetDatum(finish_time),
|
||||
CStringGetTextDatum(tz));
|
||||
|
||||
timebucket_fini = DirectFunctionCall3(ts_timestamptz_bucket,
|
||||
schedint_datum,
|
||||
TimestampTzGetDatum(finish_time),
|
||||
TimestampTzGetDatum(initial_start));
|
||||
/* always the next time_bucket */
|
||||
result = DirectFunctionCall2(timestamptz_pl_interval, timebucket_fini, schedint_datum);
|
||||
timebucket_init = DirectFunctionCall3(ts_timestamptz_timezone_bucket,
|
||||
schedint_datum,
|
||||
TimestampTzGetDatum(initial_start),
|
||||
CStringGetTextDatum(tz));
|
||||
}
|
||||
/* always the next bucket */
|
||||
timebucket_fini =
|
||||
DirectFunctionCall2(timestamptz_pl_interval, timebucket_fini, schedint_datum);
|
||||
/* get the number of months between them */
|
||||
Datum year_init =
|
||||
DirectFunctionCall2(timestamptz_part, CStringGetTextDatum("year"), timebucket_init);
|
||||
Datum year_fini =
|
||||
DirectFunctionCall2(timestamptz_part, CStringGetTextDatum("year"), timebucket_fini);
|
||||
|
||||
Datum month_init =
|
||||
DirectFunctionCall2(timestamptz_part, CStringGetTextDatum("month"), timebucket_init);
|
||||
Datum month_fini =
|
||||
DirectFunctionCall2(timestamptz_part, CStringGetTextDatum("month"), timebucket_fini);
|
||||
|
||||
/* convert everything to months */
|
||||
float8 month_diff = DatumGetFloat8(year_fini) * 12 + DatumGetFloat8(month_fini) -
|
||||
(DatumGetFloat8(year_init) * 12 + DatumGetFloat8(month_init));
|
||||
|
||||
Datum months_to_add = DirectFunctionCall2(interval_mul,
|
||||
IntervalPGetDatum(&one_month),
|
||||
Float8GetDatum(month_diff));
|
||||
result = DirectFunctionCall2(timestamptz_pl_interval,
|
||||
TimestampTzGetDatum(initial_start),
|
||||
months_to_add);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *tz = text_to_cstring(timezone);
|
||||
timebucket_fini = DirectFunctionCall4(ts_timestamptz_timezone_bucket,
|
||||
schedint_datum,
|
||||
TimestampTzGetDatum(finish_time),
|
||||
CStringGetTextDatum(tz),
|
||||
TimestampTzGetDatum(initial_start));
|
||||
/* always the next time_bucket */
|
||||
result = DirectFunctionCall2(timestamptz_pl_interval, timebucket_fini, schedint_datum);
|
||||
|
||||
offset = DirectFunctionCall3(ts_timestamptz_timezone_bucket,
|
||||
schedint_datum,
|
||||
TimestampTzGetDatum(initial_start),
|
||||
CStringGetTextDatum(tz));
|
||||
if (timezone == NULL)
|
||||
{
|
||||
/* it is safe to use the origin in time_bucket calculation */
|
||||
timebucket_fini = DirectFunctionCall3(ts_timestamptz_bucket,
|
||||
schedint_datum,
|
||||
TimestampTzGetDatum(finish_time),
|
||||
TimestampTzGetDatum(initial_start));
|
||||
result = timebucket_fini;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *tz = text_to_cstring(timezone);
|
||||
timebucket_fini = DirectFunctionCall4(ts_timestamptz_timezone_bucket,
|
||||
schedint_datum,
|
||||
TimestampTzGetDatum(finish_time),
|
||||
CStringGetTextDatum(tz),
|
||||
TimestampTzGetDatum(initial_start));
|
||||
result = timebucket_fini;
|
||||
}
|
||||
}
|
||||
|
||||
offset = DirectFunctionCall2(timestamp_mi, TimestampTzGetDatum(initial_start), offset);
|
||||
/* if we have a month component, the origin doesn't work so we must manually
|
||||
include the offset */
|
||||
if (schedule_interval->month)
|
||||
{
|
||||
result = DirectFunctionCall2(timestamptz_pl_interval, result, offset);
|
||||
}
|
||||
/*
|
||||
* adding the schedule interval above to get the next bucket might still not hit
|
||||
* the next bucket if we are crossing DST. So we can end up with a next_start value
|
||||
* that is actually less than the finish time of the job. Hence, we have to make sure
|
||||
* the next scheduled slot we compute is in the future and not in the past
|
||||
*/
|
||||
while (DatumGetTimestampTz(result) <= finish_time)
|
||||
{
|
||||
result = DirectFunctionCall2(timestamptz_pl_interval, result, schedint_datum);
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
807
tsl/test/expected/fixed_schedules.out
Normal file
807
tsl/test/expected/fixed_schedules.out
Normal file
@ -0,0 +1,807 @@
|
||||
-- This file and its contents are licensed under the Timescale License.
|
||||
-- Please see the included NOTICE for copyright information and
|
||||
-- LICENSE-TIMESCALE for a copy of the license.
|
||||
\c :TEST_DBNAME :ROLE_SUPERUSER
|
||||
CREATE OR REPLACE FUNCTION ts_test_next_scheduled_execution_slot(schedule_interval INTERVAL, finish_time TIMESTAMPTZ, initial_start TIMESTAMPTZ, timezone TEXT = NULL)
|
||||
RETURNS TIMESTAMPTZ AS :MODULE_PATHNAME LANGUAGE C VOLATILE;
|
||||
\set client_min_messages = DEBUG;
|
||||
select '2023-01-02 11:53:19.059771+02'::timestamptz as finish_time \gset
|
||||
select :'finish_time'::timestamptz - interval '5 sec' as start_time \gset
|
||||
-- years
|
||||
select ts_test_next_scheduled_execution_slot('1 year', :'finish_time'::timestamptz, :'start_time'::timestamptz) as "1 yr",
|
||||
ts_test_next_scheduled_execution_slot('1 year', :'finish_time'::timestamptz, :'start_time'::timestamptz, 'Europe/Athens') as "1 yr timezone",
|
||||
ts_test_next_scheduled_execution_slot('10 year', :'finish_time'::timestamptz, :'start_time'::timestamptz) as "10 yr",
|
||||
ts_test_next_scheduled_execution_slot('10 year', :'finish_time'::timestamptz, :'start_time'::timestamptz, 'Europe/Athens') as "10 yr timezone";
|
||||
1 yr | 1 yr timezone | 10 yr | 10 yr timezone
|
||||
-------------------------------------+-------------------------------------+-------------------------------------+-------------------------------------
|
||||
Tue Jan 02 01:53:14.059771 2024 PST | Tue Jan 02 01:53:14.059771 2024 PST | Sun Jan 02 01:53:14.059771 2033 PST | Sun Jan 02 01:53:14.059771 2033 PST
|
||||
(1 row)
|
||||
|
||||
-- weeks
|
||||
select ts_test_next_scheduled_execution_slot('1 week', :'finish_time'::timestamptz, :'start_time'::timestamptz) as "1 week",
|
||||
ts_test_next_scheduled_execution_slot('1 week', :'finish_time'::timestamptz, :'start_time'::timestamptz, 'Europe/Athens') as "1 week timezone",
|
||||
ts_test_next_scheduled_execution_slot('2 week', :'finish_time'::timestamptz, :'start_time'::timestamptz) as "2 week",
|
||||
ts_test_next_scheduled_execution_slot('2 week', :'finish_time'::timestamptz, :'start_time'::timestamptz, 'Europe/Athens') as "2 week timezone";
|
||||
1 week | 1 week timezone | 2 week | 2 week timezone
|
||||
-------------------------------------+-------------------------------------+-------------------------------------+-------------------------------------
|
||||
Mon Jan 09 01:53:14.059771 2023 PST | Mon Jan 09 01:53:14.059771 2023 PST | Mon Jan 16 01:53:14.059771 2023 PST | Mon Jan 16 01:53:14.059771 2023 PST
|
||||
(1 row)
|
||||
|
||||
-- months
|
||||
select ts_test_next_scheduled_execution_slot('1 month', :'finish_time'::timestamptz, :'start_time'::timestamptz) as "1 month",
|
||||
ts_test_next_scheduled_execution_slot('1 month', :'finish_time'::timestamptz, :'start_time'::timestamptz, 'Europe/Athens') as "1 month timezone",
|
||||
ts_test_next_scheduled_execution_slot('2 month', :'finish_time'::timestamptz, :'start_time'::timestamptz) as "2 month",
|
||||
ts_test_next_scheduled_execution_slot('2 month', :'finish_time'::timestamptz, :'start_time'::timestamptz, 'Europe/Athens') as "2 month timezone";
|
||||
1 month | 1 month timezone | 2 month | 2 month timezone
|
||||
-------------------------------------+-------------------------------------+-------------------------------------+-------------------------------------
|
||||
Thu Feb 02 01:53:14.059771 2023 PST | Thu Feb 02 01:53:14.059771 2023 PST | Thu Mar 02 01:53:14.059771 2023 PST | Thu Mar 02 01:53:14.059771 2023 PST
|
||||
(1 row)
|
||||
|
||||
-- timezone in Berlin changes between 1 and 2 am
|
||||
\set BUCKET_WIDTH_WINTER_SUMMER 'INTERVAL \'1 hour\''
|
||||
\set BUCKET_WIDTH_SUMMER_WINTER 'INTERVAL \'1 hour\''
|
||||
\set START_TIME_BEFORE_SUMMER_SWITCH 'TIMESTAMPTZ \'2022-03-27 01:00:00\''
|
||||
\set FINISH_TIME_AFTER_SUMMER_SWITCH 'TIMESTAMPTZ \'2022-03-27 01:19:20\''
|
||||
\set START_TIME_BEFORE_WINTER_SWITCH 'TIMESTAMPTZ \'2022-10-30 01:01:00\''
|
||||
\set FINISH_TIME_AFTER_WINTER_SWITCH 'TIMESTAMPTZ \'2022-10-30 01:10:19\''
|
||||
\ir include/scheduler_fixed_common.sql
|
||||
-- This file and its contents are licensed under the Timescale License.
|
||||
-- Please see the included NOTICE for copyright information and
|
||||
-- LICENSE-TIMESCALE for a copy of the license.
|
||||
\c :TEST_DBNAME :ROLE_SUPERUSER
|
||||
CREATE OR REPLACE FUNCTION ts_test_next_scheduled_execution_slot(schedule_interval INTERVAL, finish_time TIMESTAMPTZ, initial_start TIMESTAMPTZ, timezone TEXT = NULL)
|
||||
RETURNS TIMESTAMPTZ AS :MODULE_PATHNAME LANGUAGE C VOLATILE;
|
||||
\set client_min_messages = DEBUG;
|
||||
-- test what happens across DST
|
||||
-- go from +1 to +2
|
||||
set timezone to 'Europe/Berlin';
|
||||
-- DST switch on March 27th 2022, in particular, between 1am and 2 am (old time)
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :FINISH_TIME_AFTER_SUMMER_SWITCH, :START_TIME_BEFORE_SUMMER_SWITCH) as t1 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :FINISH_TIME_AFTER_SUMMER_SWITCH, :START_TIME_BEFORE_SUMMER_SWITCH, timezone => 'Europe/Berlin')
|
||||
as t1_tz \gset
|
||||
select :START_TIME_BEFORE_SUMMER_SWITCH as initial_start_summer_switch, :FINISH_TIME_AFTER_SUMMER_SWITCH as first_finish_time_summer_switch;
|
||||
initial_start_summer_switch | first_finish_time_summer_switch
|
||||
------------------------------+---------------------------------
|
||||
Sun Mar 27 01:00:00 2022 CET | Sun Mar 27 01:19:20 2022 CET
|
||||
(1 row)
|
||||
|
||||
select :'t1' as without_timezone, :'t1_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Sun Mar 27 03:00:00 2022 CEST | Sun Mar 27 03:00:00 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t1'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t2 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t1_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, timezone => 'Europe/Berlin') as t2_tz \gset
|
||||
select :'t2' as without_timezone, :'t2_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Sun Mar 27 04:00:00 2022 CEST | Sun Mar 27 04:00:00 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t2'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t3 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t2_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, timezone => 'Europe/Berlin') as t3_tz \gset
|
||||
select :'t3' as without_timezone, :'t3_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Sun Mar 27 05:00:00 2022 CEST | Sun Mar 27 05:00:00 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t3'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t4 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t3_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, 'Europe/Berlin') as t4_tz \gset
|
||||
select :'t4' as without_timezone, :'t4_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Sun Mar 27 06:00:00 2022 CEST | Sun Mar 27 06:00:00 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t5 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, 'Europe/Berlin') as t5_tz \gset
|
||||
select :'t5' as without_timezone, :'t5_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Sun Mar 27 07:00:00 2022 CEST | Sun Mar 27 07:00:00 2022 CEST
|
||||
(1 row)
|
||||
|
||||
--------- and then +2 to +1
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :FINISH_TIME_AFTER_WINTER_SWITCH, :START_TIME_BEFORE_WINTER_SWITCH) as t1 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :FINISH_TIME_AFTER_WINTER_SWITCH, :START_TIME_BEFORE_WINTER_SWITCH, timezone => 'Europe/Berlin')
|
||||
as t1_tz \gset
|
||||
select :START_TIME_BEFORE_WINTER_SWITCH as initial_start_winter_switch, :FINISH_TIME_AFTER_WINTER_SWITCH as first_finish_time_winter_switch;
|
||||
initial_start_winter_switch | first_finish_time_winter_switch
|
||||
-------------------------------+---------------------------------
|
||||
Sun Oct 30 01:01:00 2022 CEST | Sun Oct 30 01:10:19 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select :'t1' as without_timezone, :'t1_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Sun Oct 30 02:01:00 2022 CEST | Sun Oct 30 02:01:00 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t1'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH) as t2 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t1_tz'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH, timezone => 'Europe/Berlin') as t2_tz \gset
|
||||
select :'t2' as without_timezone, :'t2_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Sun Oct 30 02:01:00 2022 CET | Sun Oct 30 02:01:00 2022 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t2'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH) as t3 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t2_tz'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH, timezone => 'Europe/Berlin') as t3_tz \gset
|
||||
select :'t3' as without_timezone, :'t3_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Sun Oct 30 03:01:00 2022 CET | Sun Oct 30 03:01:00 2022 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t3'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH) as t4 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t3_tz'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH, 'Europe/Berlin') as t4_tz \gset
|
||||
select :'t4' as without_timezone, :'t4_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Sun Oct 30 04:01:00 2022 CET | Sun Oct 30 04:01:00 2022 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t5 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, 'Europe/Berlin') as t5_tz \gset
|
||||
select :'t5' as without_timezone, :'t5_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Sun Oct 30 05:00:00 2022 CET | Sun Oct 30 05:00:00 2022 CET
|
||||
(1 row)
|
||||
|
||||
\set BUCKET_WIDTH_WINTER_SUMMER 'INTERVAL \'1 day\''
|
||||
\set BUCKET_WIDTH_SUMMER_WINTER 'INTERVAL \'1 day\''
|
||||
\ir include/scheduler_fixed_common.sql
|
||||
-- This file and its contents are licensed under the Timescale License.
|
||||
-- Please see the included NOTICE for copyright information and
|
||||
-- LICENSE-TIMESCALE for a copy of the license.
|
||||
\c :TEST_DBNAME :ROLE_SUPERUSER
|
||||
CREATE OR REPLACE FUNCTION ts_test_next_scheduled_execution_slot(schedule_interval INTERVAL, finish_time TIMESTAMPTZ, initial_start TIMESTAMPTZ, timezone TEXT = NULL)
|
||||
RETURNS TIMESTAMPTZ AS :MODULE_PATHNAME LANGUAGE C VOLATILE;
|
||||
\set client_min_messages = DEBUG;
|
||||
-- test what happens across DST
|
||||
-- go from +1 to +2
|
||||
set timezone to 'Europe/Berlin';
|
||||
-- DST switch on March 27th 2022, in particular, between 1am and 2 am (old time)
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :FINISH_TIME_AFTER_SUMMER_SWITCH, :START_TIME_BEFORE_SUMMER_SWITCH) as t1 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :FINISH_TIME_AFTER_SUMMER_SWITCH, :START_TIME_BEFORE_SUMMER_SWITCH, timezone => 'Europe/Berlin')
|
||||
as t1_tz \gset
|
||||
select :START_TIME_BEFORE_SUMMER_SWITCH as initial_start_summer_switch, :FINISH_TIME_AFTER_SUMMER_SWITCH as first_finish_time_summer_switch;
|
||||
initial_start_summer_switch | first_finish_time_summer_switch
|
||||
------------------------------+---------------------------------
|
||||
Sun Mar 27 01:00:00 2022 CET | Sun Mar 27 01:19:20 2022 CET
|
||||
(1 row)
|
||||
|
||||
select :'t1' as without_timezone, :'t1_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Mon Mar 28 01:00:00 2022 CEST | Mon Mar 28 01:00:00 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t1'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t2 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t1_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, timezone => 'Europe/Berlin') as t2_tz \gset
|
||||
select :'t2' as without_timezone, :'t2_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Tue Mar 29 01:00:00 2022 CEST | Tue Mar 29 01:00:00 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t2'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t3 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t2_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, timezone => 'Europe/Berlin') as t3_tz \gset
|
||||
select :'t3' as without_timezone, :'t3_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Tue Mar 29 02:00:00 2022 CEST | Wed Mar 30 01:00:00 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t3'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t4 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t3_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, 'Europe/Berlin') as t4_tz \gset
|
||||
select :'t4' as without_timezone, :'t4_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Wed Mar 30 02:00:00 2022 CEST | Thu Mar 31 01:00:00 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t5 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, 'Europe/Berlin') as t5_tz \gset
|
||||
select :'t5' as without_timezone, :'t5_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Thu Mar 31 02:00:00 2022 CEST | Fri Apr 01 01:00:00 2022 CEST
|
||||
(1 row)
|
||||
|
||||
--------- and then +2 to +1
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :FINISH_TIME_AFTER_WINTER_SWITCH, :START_TIME_BEFORE_WINTER_SWITCH) as t1 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :FINISH_TIME_AFTER_WINTER_SWITCH, :START_TIME_BEFORE_WINTER_SWITCH, timezone => 'Europe/Berlin')
|
||||
as t1_tz \gset
|
||||
select :START_TIME_BEFORE_WINTER_SWITCH as initial_start_winter_switch, :FINISH_TIME_AFTER_WINTER_SWITCH as first_finish_time_winter_switch;
|
||||
initial_start_winter_switch | first_finish_time_winter_switch
|
||||
-------------------------------+---------------------------------
|
||||
Sun Oct 30 01:01:00 2022 CEST | Sun Oct 30 01:10:19 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select :'t1' as without_timezone, :'t1_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Mon Oct 31 01:01:00 2022 CET | Mon Oct 31 01:01:00 2022 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t1'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH) as t2 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t1_tz'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH, timezone => 'Europe/Berlin') as t2_tz \gset
|
||||
select :'t2' as without_timezone, :'t2_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Tue Nov 01 00:01:00 2022 CET | Tue Nov 01 01:01:00 2022 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t2'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH) as t3 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t2_tz'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH, timezone => 'Europe/Berlin') as t3_tz \gset
|
||||
select :'t3' as without_timezone, :'t3_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Wed Nov 02 00:01:00 2022 CET | Wed Nov 02 01:01:00 2022 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t3'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH) as t4 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t3_tz'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH, 'Europe/Berlin') as t4_tz \gset
|
||||
select :'t4' as without_timezone, :'t4_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Thu Nov 03 00:01:00 2022 CET | Thu Nov 03 01:01:00 2022 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t5 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, 'Europe/Berlin') as t5_tz \gset
|
||||
select :'t5' as without_timezone, :'t5_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Thu Nov 03 01:00:00 2022 CET | Fri Nov 04 01:00:00 2022 CET
|
||||
(1 row)
|
||||
|
||||
\set BUCKET_WIDTH_WINTER_SUMMER 'INTERVAL \'1 week\''
|
||||
\set BUCKET_WIDTH_SUMMER_WINTER 'INTERVAL \'1 week\''
|
||||
\ir include/scheduler_fixed_common.sql
|
||||
-- This file and its contents are licensed under the Timescale License.
|
||||
-- Please see the included NOTICE for copyright information and
|
||||
-- LICENSE-TIMESCALE for a copy of the license.
|
||||
\c :TEST_DBNAME :ROLE_SUPERUSER
|
||||
CREATE OR REPLACE FUNCTION ts_test_next_scheduled_execution_slot(schedule_interval INTERVAL, finish_time TIMESTAMPTZ, initial_start TIMESTAMPTZ, timezone TEXT = NULL)
|
||||
RETURNS TIMESTAMPTZ AS :MODULE_PATHNAME LANGUAGE C VOLATILE;
|
||||
\set client_min_messages = DEBUG;
|
||||
-- test what happens across DST
|
||||
-- go from +1 to +2
|
||||
set timezone to 'Europe/Berlin';
|
||||
-- DST switch on March 27th 2022, in particular, between 1am and 2 am (old time)
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :FINISH_TIME_AFTER_SUMMER_SWITCH, :START_TIME_BEFORE_SUMMER_SWITCH) as t1 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :FINISH_TIME_AFTER_SUMMER_SWITCH, :START_TIME_BEFORE_SUMMER_SWITCH, timezone => 'Europe/Berlin')
|
||||
as t1_tz \gset
|
||||
select :START_TIME_BEFORE_SUMMER_SWITCH as initial_start_summer_switch, :FINISH_TIME_AFTER_SUMMER_SWITCH as first_finish_time_summer_switch;
|
||||
initial_start_summer_switch | first_finish_time_summer_switch
|
||||
------------------------------+---------------------------------
|
||||
Sun Mar 27 01:00:00 2022 CET | Sun Mar 27 01:19:20 2022 CET
|
||||
(1 row)
|
||||
|
||||
select :'t1' as without_timezone, :'t1_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Sun Apr 03 01:00:00 2022 CEST | Sun Apr 03 01:00:00 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t1'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t2 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t1_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, timezone => 'Europe/Berlin') as t2_tz \gset
|
||||
select :'t2' as without_timezone, :'t2_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Sun Apr 10 01:00:00 2022 CEST | Sun Apr 10 01:00:00 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t2'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t3 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t2_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, timezone => 'Europe/Berlin') as t3_tz \gset
|
||||
select :'t3' as without_timezone, :'t3_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Sun Apr 10 02:00:00 2022 CEST | Sun Apr 17 01:00:00 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t3'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t4 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t3_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, 'Europe/Berlin') as t4_tz \gset
|
||||
select :'t4' as without_timezone, :'t4_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Sun Apr 17 02:00:00 2022 CEST | Sun Apr 24 01:00:00 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t5 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, 'Europe/Berlin') as t5_tz \gset
|
||||
select :'t5' as without_timezone, :'t5_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Sun Apr 24 02:00:00 2022 CEST | Sun May 01 01:00:00 2022 CEST
|
||||
(1 row)
|
||||
|
||||
--------- and then +2 to +1
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :FINISH_TIME_AFTER_WINTER_SWITCH, :START_TIME_BEFORE_WINTER_SWITCH) as t1 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :FINISH_TIME_AFTER_WINTER_SWITCH, :START_TIME_BEFORE_WINTER_SWITCH, timezone => 'Europe/Berlin')
|
||||
as t1_tz \gset
|
||||
select :START_TIME_BEFORE_WINTER_SWITCH as initial_start_winter_switch, :FINISH_TIME_AFTER_WINTER_SWITCH as first_finish_time_winter_switch;
|
||||
initial_start_winter_switch | first_finish_time_winter_switch
|
||||
-------------------------------+---------------------------------
|
||||
Sun Oct 30 01:01:00 2022 CEST | Sun Oct 30 01:10:19 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select :'t1' as without_timezone, :'t1_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Sun Nov 06 01:01:00 2022 CET | Sun Nov 06 01:01:00 2022 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t1'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH) as t2 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t1_tz'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH, timezone => 'Europe/Berlin') as t2_tz \gset
|
||||
select :'t2' as without_timezone, :'t2_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Sun Nov 13 00:01:00 2022 CET | Sun Nov 13 01:01:00 2022 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t2'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH) as t3 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t2_tz'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH, timezone => 'Europe/Berlin') as t3_tz \gset
|
||||
select :'t3' as without_timezone, :'t3_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Sun Nov 20 00:01:00 2022 CET | Sun Nov 20 01:01:00 2022 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t3'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH) as t4 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t3_tz'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH, 'Europe/Berlin') as t4_tz \gset
|
||||
select :'t4' as without_timezone, :'t4_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Sun Nov 27 00:01:00 2022 CET | Sun Nov 27 01:01:00 2022 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t5 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, 'Europe/Berlin') as t5_tz \gset
|
||||
select :'t5' as without_timezone, :'t5_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Sun Nov 27 01:00:00 2022 CET | Sun Dec 04 01:00:00 2022 CET
|
||||
(1 row)
|
||||
|
||||
\set BUCKET_WIDTH_WINTER_SUMMER 'INTERVAL \'1 month\''
|
||||
\set BUCKET_WIDTH_SUMMER_WINTER 'INTERVAL \'1 month\''
|
||||
\ir include/scheduler_fixed_common.sql
|
||||
-- This file and its contents are licensed under the Timescale License.
|
||||
-- Please see the included NOTICE for copyright information and
|
||||
-- LICENSE-TIMESCALE for a copy of the license.
|
||||
\c :TEST_DBNAME :ROLE_SUPERUSER
|
||||
CREATE OR REPLACE FUNCTION ts_test_next_scheduled_execution_slot(schedule_interval INTERVAL, finish_time TIMESTAMPTZ, initial_start TIMESTAMPTZ, timezone TEXT = NULL)
|
||||
RETURNS TIMESTAMPTZ AS :MODULE_PATHNAME LANGUAGE C VOLATILE;
|
||||
\set client_min_messages = DEBUG;
|
||||
-- test what happens across DST
|
||||
-- go from +1 to +2
|
||||
set timezone to 'Europe/Berlin';
|
||||
-- DST switch on March 27th 2022, in particular, between 1am and 2 am (old time)
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :FINISH_TIME_AFTER_SUMMER_SWITCH, :START_TIME_BEFORE_SUMMER_SWITCH) as t1 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :FINISH_TIME_AFTER_SUMMER_SWITCH, :START_TIME_BEFORE_SUMMER_SWITCH, timezone => 'Europe/Berlin')
|
||||
as t1_tz \gset
|
||||
select :START_TIME_BEFORE_SUMMER_SWITCH as initial_start_summer_switch, :FINISH_TIME_AFTER_SUMMER_SWITCH as first_finish_time_summer_switch;
|
||||
initial_start_summer_switch | first_finish_time_summer_switch
|
||||
------------------------------+---------------------------------
|
||||
Sun Mar 27 01:00:00 2022 CET | Sun Mar 27 01:19:20 2022 CET
|
||||
(1 row)
|
||||
|
||||
select :'t1' as without_timezone, :'t1_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Wed Apr 27 01:00:00 2022 CEST | Wed Apr 27 01:00:00 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t1'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t2 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t1_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, timezone => 'Europe/Berlin') as t2_tz \gset
|
||||
select :'t2' as without_timezone, :'t2_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Fri May 27 01:00:00 2022 CEST | Fri May 27 01:00:00 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t2'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t3 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t2_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, timezone => 'Europe/Berlin') as t3_tz \gset
|
||||
select :'t3' as without_timezone, :'t3_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Mon Jun 27 01:00:00 2022 CEST | Mon Jun 27 01:00:00 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t3'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t4 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t3_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, 'Europe/Berlin') as t4_tz \gset
|
||||
select :'t4' as without_timezone, :'t4_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Wed Jul 27 01:00:00 2022 CEST | Wed Jul 27 01:00:00 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t5 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, 'Europe/Berlin') as t5_tz \gset
|
||||
select :'t5' as without_timezone, :'t5_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Sat Aug 27 01:00:00 2022 CEST | Sat Aug 27 01:00:00 2022 CEST
|
||||
(1 row)
|
||||
|
||||
--------- and then +2 to +1
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :FINISH_TIME_AFTER_WINTER_SWITCH, :START_TIME_BEFORE_WINTER_SWITCH) as t1 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :FINISH_TIME_AFTER_WINTER_SWITCH, :START_TIME_BEFORE_WINTER_SWITCH, timezone => 'Europe/Berlin')
|
||||
as t1_tz \gset
|
||||
select :START_TIME_BEFORE_WINTER_SWITCH as initial_start_winter_switch, :FINISH_TIME_AFTER_WINTER_SWITCH as first_finish_time_winter_switch;
|
||||
initial_start_winter_switch | first_finish_time_winter_switch
|
||||
-------------------------------+---------------------------------
|
||||
Sun Oct 30 01:01:00 2022 CEST | Sun Oct 30 01:10:19 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select :'t1' as without_timezone, :'t1_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Wed Nov 30 01:01:00 2022 CET | Wed Nov 30 01:01:00 2022 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t1'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH) as t2 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t1_tz'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH, timezone => 'Europe/Berlin') as t2_tz \gset
|
||||
select :'t2' as without_timezone, :'t2_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Fri Dec 30 01:01:00 2022 CET | Fri Dec 30 01:01:00 2022 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t2'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH) as t3 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t2_tz'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH, timezone => 'Europe/Berlin') as t3_tz \gset
|
||||
select :'t3' as without_timezone, :'t3_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Mon Jan 30 01:01:00 2023 CET | Mon Jan 30 01:01:00 2023 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t3'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH) as t4 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t3_tz'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH, 'Europe/Berlin') as t4_tz \gset
|
||||
select :'t4' as without_timezone, :'t4_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Tue Feb 28 01:01:00 2023 CET | Tue Feb 28 01:01:00 2023 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t5 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, 'Europe/Berlin') as t5_tz \gset
|
||||
select :'t5' as without_timezone, :'t5_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Mon Mar 27 01:00:00 2023 CEST | Mon Mar 27 01:00:00 2023 CEST
|
||||
(1 row)
|
||||
|
||||
\set BUCKET_WIDTH_WINTER_SUMMER 'INTERVAL \'1 year\''
|
||||
\set BUCKET_WIDTH_SUMMER_WINTER 'INTERVAL \'1 year\''
|
||||
\ir include/scheduler_fixed_common.sql
|
||||
-- This file and its contents are licensed under the Timescale License.
|
||||
-- Please see the included NOTICE for copyright information and
|
||||
-- LICENSE-TIMESCALE for a copy of the license.
|
||||
\c :TEST_DBNAME :ROLE_SUPERUSER
|
||||
CREATE OR REPLACE FUNCTION ts_test_next_scheduled_execution_slot(schedule_interval INTERVAL, finish_time TIMESTAMPTZ, initial_start TIMESTAMPTZ, timezone TEXT = NULL)
|
||||
RETURNS TIMESTAMPTZ AS :MODULE_PATHNAME LANGUAGE C VOLATILE;
|
||||
\set client_min_messages = DEBUG;
|
||||
-- test what happens across DST
|
||||
-- go from +1 to +2
|
||||
set timezone to 'Europe/Berlin';
|
||||
-- DST switch on March 27th 2022, in particular, between 1am and 2 am (old time)
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :FINISH_TIME_AFTER_SUMMER_SWITCH, :START_TIME_BEFORE_SUMMER_SWITCH) as t1 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :FINISH_TIME_AFTER_SUMMER_SWITCH, :START_TIME_BEFORE_SUMMER_SWITCH, timezone => 'Europe/Berlin')
|
||||
as t1_tz \gset
|
||||
select :START_TIME_BEFORE_SUMMER_SWITCH as initial_start_summer_switch, :FINISH_TIME_AFTER_SUMMER_SWITCH as first_finish_time_summer_switch;
|
||||
initial_start_summer_switch | first_finish_time_summer_switch
|
||||
------------------------------+---------------------------------
|
||||
Sun Mar 27 01:00:00 2022 CET | Sun Mar 27 01:19:20 2022 CET
|
||||
(1 row)
|
||||
|
||||
select :'t1' as without_timezone, :'t1_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Mon Mar 27 01:00:00 2023 CEST | Mon Mar 27 01:00:00 2023 CEST
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t1'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t2 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t1_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, timezone => 'Europe/Berlin') as t2_tz \gset
|
||||
select :'t2' as without_timezone, :'t2_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Wed Mar 27 01:00:00 2024 CET | Wed Mar 27 01:00:00 2024 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t2'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t3 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t2_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, timezone => 'Europe/Berlin') as t3_tz \gset
|
||||
select :'t3' as without_timezone, :'t3_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Thu Mar 27 01:00:00 2025 CET | Thu Mar 27 01:00:00 2025 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t3'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t4 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t3_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, 'Europe/Berlin') as t4_tz \gset
|
||||
select :'t4' as without_timezone, :'t4_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Fri Mar 27 01:00:00 2026 CET | Fri Mar 27 01:00:00 2026 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t5 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, 'Europe/Berlin') as t5_tz \gset
|
||||
select :'t5' as without_timezone, :'t5_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Sat Mar 27 01:00:00 2027 CET | Sat Mar 27 01:00:00 2027 CET
|
||||
(1 row)
|
||||
|
||||
--------- and then +2 to +1
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :FINISH_TIME_AFTER_WINTER_SWITCH, :START_TIME_BEFORE_WINTER_SWITCH) as t1 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :FINISH_TIME_AFTER_WINTER_SWITCH, :START_TIME_BEFORE_WINTER_SWITCH, timezone => 'Europe/Berlin')
|
||||
as t1_tz \gset
|
||||
select :START_TIME_BEFORE_WINTER_SWITCH as initial_start_winter_switch, :FINISH_TIME_AFTER_WINTER_SWITCH as first_finish_time_winter_switch;
|
||||
initial_start_winter_switch | first_finish_time_winter_switch
|
||||
-------------------------------+---------------------------------
|
||||
Sun Oct 30 01:01:00 2022 CEST | Sun Oct 30 01:10:19 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select :'t1' as without_timezone, :'t1_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Mon Oct 30 01:01:00 2023 CET | Mon Oct 30 01:01:00 2023 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t1'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH) as t2 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t1_tz'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH, timezone => 'Europe/Berlin') as t2_tz \gset
|
||||
select :'t2' as without_timezone, :'t2_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Wed Oct 30 01:01:00 2024 CET | Wed Oct 30 01:01:00 2024 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t2'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH) as t3 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t2_tz'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH, timezone => 'Europe/Berlin') as t3_tz \gset
|
||||
select :'t3' as without_timezone, :'t3_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Thu Oct 30 01:01:00 2025 CET | Thu Oct 30 01:01:00 2025 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t3'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH) as t4 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t3_tz'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH, 'Europe/Berlin') as t4_tz \gset
|
||||
select :'t4' as without_timezone, :'t4_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Fri Oct 30 01:01:00 2026 CET | Fri Oct 30 01:01:00 2026 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t5 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, 'Europe/Berlin') as t5_tz \gset
|
||||
select :'t5' as without_timezone, :'t5_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Sat Mar 27 01:00:00 2027 CET | Sat Mar 27 01:00:00 2027 CET
|
||||
(1 row)
|
||||
|
||||
\set BUCKET_WIDTH_WINTER_SUMMER 'INTERVAL \'2 month\''
|
||||
\set BUCKET_WIDTH_SUMMER_WINTER 'INTERVAL \'2 month\''
|
||||
\ir include/scheduler_fixed_common.sql
|
||||
-- This file and its contents are licensed under the Timescale License.
|
||||
-- Please see the included NOTICE for copyright information and
|
||||
-- LICENSE-TIMESCALE for a copy of the license.
|
||||
\c :TEST_DBNAME :ROLE_SUPERUSER
|
||||
CREATE OR REPLACE FUNCTION ts_test_next_scheduled_execution_slot(schedule_interval INTERVAL, finish_time TIMESTAMPTZ, initial_start TIMESTAMPTZ, timezone TEXT = NULL)
|
||||
RETURNS TIMESTAMPTZ AS :MODULE_PATHNAME LANGUAGE C VOLATILE;
|
||||
\set client_min_messages = DEBUG;
|
||||
-- test what happens across DST
|
||||
-- go from +1 to +2
|
||||
set timezone to 'Europe/Berlin';
|
||||
-- DST switch on March 27th 2022, in particular, between 1am and 2 am (old time)
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :FINISH_TIME_AFTER_SUMMER_SWITCH, :START_TIME_BEFORE_SUMMER_SWITCH) as t1 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :FINISH_TIME_AFTER_SUMMER_SWITCH, :START_TIME_BEFORE_SUMMER_SWITCH, timezone => 'Europe/Berlin')
|
||||
as t1_tz \gset
|
||||
select :START_TIME_BEFORE_SUMMER_SWITCH as initial_start_summer_switch, :FINISH_TIME_AFTER_SUMMER_SWITCH as first_finish_time_summer_switch;
|
||||
initial_start_summer_switch | first_finish_time_summer_switch
|
||||
------------------------------+---------------------------------
|
||||
Sun Mar 27 01:00:00 2022 CET | Sun Mar 27 01:19:20 2022 CET
|
||||
(1 row)
|
||||
|
||||
select :'t1' as without_timezone, :'t1_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Fri May 27 01:00:00 2022 CEST | Fri May 27 01:00:00 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t1'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t2 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t1_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, timezone => 'Europe/Berlin') as t2_tz \gset
|
||||
select :'t2' as without_timezone, :'t2_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Wed Jul 27 01:00:00 2022 CEST | Wed Jul 27 01:00:00 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t2'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t3 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t2_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, timezone => 'Europe/Berlin') as t3_tz \gset
|
||||
select :'t3' as without_timezone, :'t3_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Tue Sep 27 01:00:00 2022 CEST | Tue Sep 27 01:00:00 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t3'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t4 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t3_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, 'Europe/Berlin') as t4_tz \gset
|
||||
select :'t4' as without_timezone, :'t4_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Sun Nov 27 01:00:00 2022 CET | Sun Nov 27 01:00:00 2022 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t5 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, 'Europe/Berlin') as t5_tz \gset
|
||||
select :'t5' as without_timezone, :'t5_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Fri Jan 27 01:00:00 2023 CET | Fri Jan 27 01:00:00 2023 CET
|
||||
(1 row)
|
||||
|
||||
--------- and then +2 to +1
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :FINISH_TIME_AFTER_WINTER_SWITCH, :START_TIME_BEFORE_WINTER_SWITCH) as t1 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :FINISH_TIME_AFTER_WINTER_SWITCH, :START_TIME_BEFORE_WINTER_SWITCH, timezone => 'Europe/Berlin')
|
||||
as t1_tz \gset
|
||||
select :START_TIME_BEFORE_WINTER_SWITCH as initial_start_winter_switch, :FINISH_TIME_AFTER_WINTER_SWITCH as first_finish_time_winter_switch;
|
||||
initial_start_winter_switch | first_finish_time_winter_switch
|
||||
-------------------------------+---------------------------------
|
||||
Sun Oct 30 01:01:00 2022 CEST | Sun Oct 30 01:10:19 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select :'t1' as without_timezone, :'t1_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Fri Dec 30 01:01:00 2022 CET | Fri Dec 30 01:01:00 2022 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t1'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH) as t2 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t1_tz'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH, timezone => 'Europe/Berlin') as t2_tz \gset
|
||||
select :'t2' as without_timezone, :'t2_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Tue Feb 28 01:01:00 2023 CET | Tue Feb 28 01:01:00 2023 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t2'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH) as t3 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t2_tz'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH, timezone => 'Europe/Berlin') as t3_tz \gset
|
||||
select :'t3' as without_timezone, :'t3_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Sun Apr 30 01:01:00 2023 CEST | Sun Apr 30 01:01:00 2023 CEST
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t3'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH) as t4 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t3_tz'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH, 'Europe/Berlin') as t4_tz \gset
|
||||
select :'t4' as without_timezone, :'t4_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Fri Jun 30 01:01:00 2023 CEST | Fri Jun 30 01:01:00 2023 CEST
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t5 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, 'Europe/Berlin') as t5_tz \gset
|
||||
select :'t5' as without_timezone, :'t5_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Thu Jul 27 01:00:00 2023 CEST | Thu Jul 27 01:00:00 2023 CEST
|
||||
(1 row)
|
||||
|
||||
\set BUCKET_WIDTH_WINTER_SUMMER 'INTERVAL \'2 year\''
|
||||
\set BUCKET_WIDTH_SUMMER_WINTER 'INTERVAL \'2 year\''
|
||||
\ir include/scheduler_fixed_common.sql
|
||||
-- This file and its contents are licensed under the Timescale License.
|
||||
-- Please see the included NOTICE for copyright information and
|
||||
-- LICENSE-TIMESCALE for a copy of the license.
|
||||
\c :TEST_DBNAME :ROLE_SUPERUSER
|
||||
CREATE OR REPLACE FUNCTION ts_test_next_scheduled_execution_slot(schedule_interval INTERVAL, finish_time TIMESTAMPTZ, initial_start TIMESTAMPTZ, timezone TEXT = NULL)
|
||||
RETURNS TIMESTAMPTZ AS :MODULE_PATHNAME LANGUAGE C VOLATILE;
|
||||
\set client_min_messages = DEBUG;
|
||||
-- test what happens across DST
|
||||
-- go from +1 to +2
|
||||
set timezone to 'Europe/Berlin';
|
||||
-- DST switch on March 27th 2022, in particular, between 1am and 2 am (old time)
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :FINISH_TIME_AFTER_SUMMER_SWITCH, :START_TIME_BEFORE_SUMMER_SWITCH) as t1 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :FINISH_TIME_AFTER_SUMMER_SWITCH, :START_TIME_BEFORE_SUMMER_SWITCH, timezone => 'Europe/Berlin')
|
||||
as t1_tz \gset
|
||||
select :START_TIME_BEFORE_SUMMER_SWITCH as initial_start_summer_switch, :FINISH_TIME_AFTER_SUMMER_SWITCH as first_finish_time_summer_switch;
|
||||
initial_start_summer_switch | first_finish_time_summer_switch
|
||||
------------------------------+---------------------------------
|
||||
Sun Mar 27 01:00:00 2022 CET | Sun Mar 27 01:19:20 2022 CET
|
||||
(1 row)
|
||||
|
||||
select :'t1' as without_timezone, :'t1_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Wed Mar 27 01:00:00 2024 CET | Wed Mar 27 01:00:00 2024 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t1'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t2 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t1_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, timezone => 'Europe/Berlin') as t2_tz \gset
|
||||
select :'t2' as without_timezone, :'t2_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Fri Mar 27 01:00:00 2026 CET | Fri Mar 27 01:00:00 2026 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t2'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t3 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t2_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, timezone => 'Europe/Berlin') as t3_tz \gset
|
||||
select :'t3' as without_timezone, :'t3_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
-------------------------------+-------------------------------
|
||||
Mon Mar 27 01:00:00 2028 CEST | Mon Mar 27 01:00:00 2028 CEST
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t3'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t4 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t3_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, 'Europe/Berlin') as t4_tz \gset
|
||||
select :'t4' as without_timezone, :'t4_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Wed Mar 27 01:00:00 2030 CET | Wed Mar 27 01:00:00 2030 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t5 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, 'Europe/Berlin') as t5_tz \gset
|
||||
select :'t5' as without_timezone, :'t5_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Sat Mar 27 01:00:00 2032 CET | Sat Mar 27 01:00:00 2032 CET
|
||||
(1 row)
|
||||
|
||||
--------- and then +2 to +1
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :FINISH_TIME_AFTER_WINTER_SWITCH, :START_TIME_BEFORE_WINTER_SWITCH) as t1 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :FINISH_TIME_AFTER_WINTER_SWITCH, :START_TIME_BEFORE_WINTER_SWITCH, timezone => 'Europe/Berlin')
|
||||
as t1_tz \gset
|
||||
select :START_TIME_BEFORE_WINTER_SWITCH as initial_start_winter_switch, :FINISH_TIME_AFTER_WINTER_SWITCH as first_finish_time_winter_switch;
|
||||
initial_start_winter_switch | first_finish_time_winter_switch
|
||||
-------------------------------+---------------------------------
|
||||
Sun Oct 30 01:01:00 2022 CEST | Sun Oct 30 01:10:19 2022 CEST
|
||||
(1 row)
|
||||
|
||||
select :'t1' as without_timezone, :'t1_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Wed Oct 30 01:01:00 2024 CET | Wed Oct 30 01:01:00 2024 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t1'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH) as t2 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t1_tz'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH, timezone => 'Europe/Berlin') as t2_tz \gset
|
||||
select :'t2' as without_timezone, :'t2_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Fri Oct 30 01:01:00 2026 CET | Fri Oct 30 01:01:00 2026 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t2'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH) as t3 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t2_tz'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH, timezone => 'Europe/Berlin') as t3_tz \gset
|
||||
select :'t3' as without_timezone, :'t3_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Mon Oct 30 01:01:00 2028 CET | Mon Oct 30 01:01:00 2028 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t3'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH) as t4 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t3_tz'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH, 'Europe/Berlin') as t4_tz \gset
|
||||
select :'t4' as without_timezone, :'t4_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Wed Oct 30 01:01:00 2030 CET | Wed Oct 30 01:01:00 2030 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t5 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, 'Europe/Berlin') as t5_tz \gset
|
||||
select :'t5' as without_timezone, :'t5_tz' as with_timezone;
|
||||
without_timezone | with_timezone
|
||||
------------------------------+------------------------------
|
||||
Sat Mar 27 01:00:00 2032 CET | Sat Mar 27 01:00:00 2032 CET
|
||||
(1 row)
|
||||
|
@ -194,3 +194,68 @@ select :'t3' as without_timezone, :'t3_tz' as with_timezone;
|
||||
-- test some unacceptable values for schedule interval
|
||||
select add_job('job_5', schedule_interval => interval '1 month 1week', initial_start => :'initial_start'::timestamptz);
|
||||
ERROR: month intervals cannot have day or time component
|
||||
\set client_min_messages = DEBUG;
|
||||
select '2023-01-02 11:53:19.059771+02'::timestamptz as finish_time \gset
|
||||
-- years
|
||||
select ts_test_next_scheduled_execution_slot('1 year', :'finish_time'::timestamptz, :'finish_time'::timestamptz - interval '3 sec');
|
||||
ts_test_next_scheduled_execution_slot
|
||||
---------------------------------------
|
||||
Tue Jan 02 10:53:16.059771 2024 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot('2 year', :'finish_time'::timestamptz, :'finish_time'::timestamptz - interval '3 sec');
|
||||
ts_test_next_scheduled_execution_slot
|
||||
---------------------------------------
|
||||
Thu Jan 02 10:53:16.059771 2025 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot('10 year', :'finish_time'::timestamptz, :'finish_time'::timestamptz - interval '3 sec');
|
||||
ts_test_next_scheduled_execution_slot
|
||||
---------------------------------------
|
||||
Sun Jan 02 10:53:16.059771 2033 CET
|
||||
(1 row)
|
||||
|
||||
-- weeks
|
||||
select ts_test_next_scheduled_execution_slot('1 week', :'finish_time'::timestamptz, :'finish_time'::timestamptz - interval '3 sec');
|
||||
ts_test_next_scheduled_execution_slot
|
||||
---------------------------------------
|
||||
Mon Jan 09 10:53:16.059771 2023 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot('2 week', :'finish_time'::timestamptz, :'finish_time'::timestamptz - interval '3 sec');
|
||||
ts_test_next_scheduled_execution_slot
|
||||
---------------------------------------
|
||||
Mon Jan 16 10:53:16.059771 2023 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot('2 week', :'finish_time'::timestamptz, :'finish_time'::timestamptz - interval '3 sec');
|
||||
ts_test_next_scheduled_execution_slot
|
||||
---------------------------------------
|
||||
Mon Jan 16 10:53:16.059771 2023 CET
|
||||
(1 row)
|
||||
|
||||
-- months
|
||||
select ts_test_next_scheduled_execution_slot('10 month', :'finish_time'::timestamptz, :'finish_time'::timestamptz - interval '3 sec');
|
||||
ts_test_next_scheduled_execution_slot
|
||||
---------------------------------------
|
||||
Thu Nov 02 10:53:16.059771 2023 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot('10 month', :'finish_time'::timestamptz, :'finish_time'::timestamptz - interval '3 sec', 'Europe/Athens');
|
||||
ts_test_next_scheduled_execution_slot
|
||||
---------------------------------------
|
||||
Thu Nov 02 10:53:16.059771 2023 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot('2 month', :'finish_time'::timestamptz, :'finish_time'::timestamptz - interval '3 sec');
|
||||
ts_test_next_scheduled_execution_slot
|
||||
---------------------------------------
|
||||
Thu Mar 02 10:53:16.059771 2023 CET
|
||||
(1 row)
|
||||
|
||||
select ts_test_next_scheduled_execution_slot('2 month', :'finish_time'::timestamptz, :'finish_time'::timestamptz - interval '3 sec', 'Europe/Athens');
|
||||
ts_test_next_scheduled_execution_slot
|
||||
---------------------------------------
|
||||
Thu Mar 02 10:53:16.059771 2023 CET
|
||||
(1 row)
|
||||
|
||||
|
@ -95,7 +95,8 @@ if(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
remote_txn.sql
|
||||
transparent_decompression_queries.sql
|
||||
tsl_tables.sql
|
||||
license_tsl.sql)
|
||||
license_tsl.sql
|
||||
fixed_schedules.sql)
|
||||
endif(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
|
||||
if((${PG_VERSION_MAJOR} GREATER_EQUAL "14"))
|
||||
|
64
tsl/test/sql/fixed_schedules.sql
Normal file
64
tsl/test/sql/fixed_schedules.sql
Normal file
@ -0,0 +1,64 @@
|
||||
-- This file and its contents are licensed under the Timescale License.
|
||||
-- Please see the included NOTICE for copyright information and
|
||||
-- LICENSE-TIMESCALE for a copy of the license.
|
||||
|
||||
\c :TEST_DBNAME :ROLE_SUPERUSER
|
||||
|
||||
CREATE OR REPLACE FUNCTION ts_test_next_scheduled_execution_slot(schedule_interval INTERVAL, finish_time TIMESTAMPTZ, initial_start TIMESTAMPTZ, timezone TEXT = NULL)
|
||||
RETURNS TIMESTAMPTZ AS :MODULE_PATHNAME LANGUAGE C VOLATILE;
|
||||
|
||||
\set client_min_messages = DEBUG;
|
||||
|
||||
select '2023-01-02 11:53:19.059771+02'::timestamptz as finish_time \gset
|
||||
select :'finish_time'::timestamptz - interval '5 sec' as start_time \gset
|
||||
|
||||
-- years
|
||||
select ts_test_next_scheduled_execution_slot('1 year', :'finish_time'::timestamptz, :'start_time'::timestamptz) as "1 yr",
|
||||
ts_test_next_scheduled_execution_slot('1 year', :'finish_time'::timestamptz, :'start_time'::timestamptz, 'Europe/Athens') as "1 yr timezone",
|
||||
ts_test_next_scheduled_execution_slot('10 year', :'finish_time'::timestamptz, :'start_time'::timestamptz) as "10 yr",
|
||||
ts_test_next_scheduled_execution_slot('10 year', :'finish_time'::timestamptz, :'start_time'::timestamptz, 'Europe/Athens') as "10 yr timezone";
|
||||
|
||||
-- weeks
|
||||
select ts_test_next_scheduled_execution_slot('1 week', :'finish_time'::timestamptz, :'start_time'::timestamptz) as "1 week",
|
||||
ts_test_next_scheduled_execution_slot('1 week', :'finish_time'::timestamptz, :'start_time'::timestamptz, 'Europe/Athens') as "1 week timezone",
|
||||
ts_test_next_scheduled_execution_slot('2 week', :'finish_time'::timestamptz, :'start_time'::timestamptz) as "2 week",
|
||||
ts_test_next_scheduled_execution_slot('2 week', :'finish_time'::timestamptz, :'start_time'::timestamptz, 'Europe/Athens') as "2 week timezone";
|
||||
|
||||
-- months
|
||||
select ts_test_next_scheduled_execution_slot('1 month', :'finish_time'::timestamptz, :'start_time'::timestamptz) as "1 month",
|
||||
ts_test_next_scheduled_execution_slot('1 month', :'finish_time'::timestamptz, :'start_time'::timestamptz, 'Europe/Athens') as "1 month timezone",
|
||||
ts_test_next_scheduled_execution_slot('2 month', :'finish_time'::timestamptz, :'start_time'::timestamptz) as "2 month",
|
||||
ts_test_next_scheduled_execution_slot('2 month', :'finish_time'::timestamptz, :'start_time'::timestamptz, 'Europe/Athens') as "2 month timezone";
|
||||
|
||||
-- timezone in Berlin changes between 1 and 2 am
|
||||
\set BUCKET_WIDTH_WINTER_SUMMER 'INTERVAL \'1 hour\''
|
||||
\set BUCKET_WIDTH_SUMMER_WINTER 'INTERVAL \'1 hour\''
|
||||
\set START_TIME_BEFORE_SUMMER_SWITCH 'TIMESTAMPTZ \'2022-03-27 01:00:00\''
|
||||
\set FINISH_TIME_AFTER_SUMMER_SWITCH 'TIMESTAMPTZ \'2022-03-27 01:19:20\''
|
||||
\set START_TIME_BEFORE_WINTER_SWITCH 'TIMESTAMPTZ \'2022-10-30 01:01:00\''
|
||||
\set FINISH_TIME_AFTER_WINTER_SWITCH 'TIMESTAMPTZ \'2022-10-30 01:10:19\''
|
||||
\ir include/scheduler_fixed_common.sql
|
||||
|
||||
\set BUCKET_WIDTH_WINTER_SUMMER 'INTERVAL \'1 day\''
|
||||
\set BUCKET_WIDTH_SUMMER_WINTER 'INTERVAL \'1 day\''
|
||||
\ir include/scheduler_fixed_common.sql
|
||||
|
||||
\set BUCKET_WIDTH_WINTER_SUMMER 'INTERVAL \'1 week\''
|
||||
\set BUCKET_WIDTH_SUMMER_WINTER 'INTERVAL \'1 week\''
|
||||
\ir include/scheduler_fixed_common.sql
|
||||
|
||||
\set BUCKET_WIDTH_WINTER_SUMMER 'INTERVAL \'1 month\''
|
||||
\set BUCKET_WIDTH_SUMMER_WINTER 'INTERVAL \'1 month\''
|
||||
\ir include/scheduler_fixed_common.sql
|
||||
|
||||
\set BUCKET_WIDTH_WINTER_SUMMER 'INTERVAL \'1 year\''
|
||||
\set BUCKET_WIDTH_SUMMER_WINTER 'INTERVAL \'1 year\''
|
||||
\ir include/scheduler_fixed_common.sql
|
||||
|
||||
\set BUCKET_WIDTH_WINTER_SUMMER 'INTERVAL \'2 month\''
|
||||
\set BUCKET_WIDTH_SUMMER_WINTER 'INTERVAL \'2 month\''
|
||||
\ir include/scheduler_fixed_common.sql
|
||||
|
||||
\set BUCKET_WIDTH_WINTER_SUMMER 'INTERVAL \'2 year\''
|
||||
\set BUCKET_WIDTH_SUMMER_WINTER 'INTERVAL \'2 year\''
|
||||
\ir include/scheduler_fixed_common.sql
|
51
tsl/test/sql/include/scheduler_fixed_common.sql
Normal file
51
tsl/test/sql/include/scheduler_fixed_common.sql
Normal file
@ -0,0 +1,51 @@
|
||||
-- This file and its contents are licensed under the Timescale License.
|
||||
-- Please see the included NOTICE for copyright information and
|
||||
-- LICENSE-TIMESCALE for a copy of the license.
|
||||
|
||||
\c :TEST_DBNAME :ROLE_SUPERUSER
|
||||
|
||||
CREATE OR REPLACE FUNCTION ts_test_next_scheduled_execution_slot(schedule_interval INTERVAL, finish_time TIMESTAMPTZ, initial_start TIMESTAMPTZ, timezone TEXT = NULL)
|
||||
RETURNS TIMESTAMPTZ AS :MODULE_PATHNAME LANGUAGE C VOLATILE;
|
||||
|
||||
\set client_min_messages = DEBUG;
|
||||
|
||||
-- test what happens across DST
|
||||
-- go from +1 to +2
|
||||
set timezone to 'Europe/Berlin';
|
||||
-- DST switch on March 27th 2022, in particular, between 1am and 2 am (old time)
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :FINISH_TIME_AFTER_SUMMER_SWITCH, :START_TIME_BEFORE_SUMMER_SWITCH) as t1 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :FINISH_TIME_AFTER_SUMMER_SWITCH, :START_TIME_BEFORE_SUMMER_SWITCH, timezone => 'Europe/Berlin')
|
||||
as t1_tz \gset
|
||||
select :START_TIME_BEFORE_SUMMER_SWITCH as initial_start_summer_switch, :FINISH_TIME_AFTER_SUMMER_SWITCH as first_finish_time_summer_switch;
|
||||
select :'t1' as without_timezone, :'t1_tz' as with_timezone;
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t1'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t2 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t1_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, timezone => 'Europe/Berlin') as t2_tz \gset
|
||||
select :'t2' as without_timezone, :'t2_tz' as with_timezone;
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t2'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t3 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t2_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, timezone => 'Europe/Berlin') as t3_tz \gset
|
||||
select :'t3' as without_timezone, :'t3_tz' as with_timezone;
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t3'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t4 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t3_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, 'Europe/Berlin') as t4_tz \gset
|
||||
select :'t4' as without_timezone, :'t4_tz' as with_timezone;
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t5 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, 'Europe/Berlin') as t5_tz \gset
|
||||
select :'t5' as without_timezone, :'t5_tz' as with_timezone;
|
||||
--------- and then +2 to +1
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :FINISH_TIME_AFTER_WINTER_SWITCH, :START_TIME_BEFORE_WINTER_SWITCH) as t1 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :FINISH_TIME_AFTER_WINTER_SWITCH, :START_TIME_BEFORE_WINTER_SWITCH, timezone => 'Europe/Berlin')
|
||||
as t1_tz \gset
|
||||
select :START_TIME_BEFORE_WINTER_SWITCH as initial_start_winter_switch, :FINISH_TIME_AFTER_WINTER_SWITCH as first_finish_time_winter_switch;
|
||||
select :'t1' as without_timezone, :'t1_tz' as with_timezone;
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t1'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH) as t2 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t1_tz'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH, timezone => 'Europe/Berlin') as t2_tz \gset
|
||||
select :'t2' as without_timezone, :'t2_tz' as with_timezone;
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t2'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH) as t3 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t2_tz'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH, timezone => 'Europe/Berlin') as t3_tz \gset
|
||||
select :'t3' as without_timezone, :'t3_tz' as with_timezone;
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t3'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH) as t4 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_SUMMER_WINTER, :'t3_tz'::timestamptz, :START_TIME_BEFORE_WINTER_SWITCH, 'Europe/Berlin') as t4_tz \gset
|
||||
select :'t4' as without_timezone, :'t4_tz' as with_timezone;
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH) as t5 \gset
|
||||
select ts_test_next_scheduled_execution_slot(:BUCKET_WIDTH_WINTER_SUMMER, :'t4_tz'::timestamptz, :START_TIME_BEFORE_SUMMER_SWITCH, 'Europe/Berlin') as t5_tz \gset
|
||||
select :'t5' as without_timezone, :'t5_tz' as with_timezone;
|
||||
|
@ -122,3 +122,21 @@ select :'t3' as without_timezone, :'t3_tz' as with_timezone;
|
||||
\set ON_ERROR_STOP 0
|
||||
-- test some unacceptable values for schedule interval
|
||||
select add_job('job_5', schedule_interval => interval '1 month 1week', initial_start => :'initial_start'::timestamptz);
|
||||
|
||||
\set client_min_messages = DEBUG;
|
||||
|
||||
select '2023-01-02 11:53:19.059771+02'::timestamptz as finish_time \gset
|
||||
|
||||
-- years
|
||||
select ts_test_next_scheduled_execution_slot('1 year', :'finish_time'::timestamptz, :'finish_time'::timestamptz - interval '3 sec');
|
||||
select ts_test_next_scheduled_execution_slot('2 year', :'finish_time'::timestamptz, :'finish_time'::timestamptz - interval '3 sec');
|
||||
select ts_test_next_scheduled_execution_slot('10 year', :'finish_time'::timestamptz, :'finish_time'::timestamptz - interval '3 sec');
|
||||
-- weeks
|
||||
select ts_test_next_scheduled_execution_slot('1 week', :'finish_time'::timestamptz, :'finish_time'::timestamptz - interval '3 sec');
|
||||
select ts_test_next_scheduled_execution_slot('2 week', :'finish_time'::timestamptz, :'finish_time'::timestamptz - interval '3 sec');
|
||||
select ts_test_next_scheduled_execution_slot('2 week', :'finish_time'::timestamptz, :'finish_time'::timestamptz - interval '3 sec');
|
||||
-- months
|
||||
select ts_test_next_scheduled_execution_slot('10 month', :'finish_time'::timestamptz, :'finish_time'::timestamptz - interval '3 sec');
|
||||
select ts_test_next_scheduled_execution_slot('10 month', :'finish_time'::timestamptz, :'finish_time'::timestamptz - interval '3 sec', 'Europe/Athens');
|
||||
select ts_test_next_scheduled_execution_slot('2 month', :'finish_time'::timestamptz, :'finish_time'::timestamptz - interval '3 sec');
|
||||
select ts_test_next_scheduled_execution_slot('2 month', :'finish_time'::timestamptz, :'finish_time'::timestamptz - interval '3 sec', 'Europe/Athens');
|
||||
|
@ -5,7 +5,7 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use TimescaleNode;
|
||||
use Test::More tests => 4;
|
||||
use Test::More tests => 5;
|
||||
|
||||
# This test checks that a job crash is reported in the job errors table
|
||||
# (that is, a record gets inserted into the table _timescaledb_internal.job_errors).
|
||||
@ -40,14 +40,20 @@ my $query_add =
|
||||
my $jobid = $node->safe_psql('postgres', "$query_add");
|
||||
is($jobid, '1000', 'job was added');
|
||||
|
||||
# sleep 10 to make sure job has started running
|
||||
$node->safe_psql('postgres', "select pg_sleep(10)");
|
||||
my $query_pid_exists = <<"END_OF_QUERY";
|
||||
select count(*) from pg_stat_activity
|
||||
where application_name like 'User-Defined Action%'
|
||||
and query like '%custom_proc_sleep60%'
|
||||
END_OF_QUERY
|
||||
# select the pid of this job in order to kill it
|
||||
my $query_pid = <<"END_OF_QUERY";
|
||||
select pid from pg_stat_activity
|
||||
where application_name like 'User-Defined Action%'
|
||||
and query like '%custom_proc_sleep60%'
|
||||
END_OF_QUERY
|
||||
|
||||
ok($node->poll_query_until('postgres', "$query_pid_exists", '1'));
|
||||
|
||||
my $pid = $node->safe_psql('postgres', "$query_pid");
|
||||
isnt($pid, "", "check the pid is not null");
|
||||
# now kill the one backend
|
||||
|
Loading…
x
Reference in New Issue
Block a user