-- 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.
--
-- Setup
--
\c :TEST_DBNAME :ROLE_SUPERUSER
CREATE OR REPLACE FUNCTION ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish(timeout INT = -1) RETURNS VOID
AS :MODULE_PATHNAME LANGUAGE C VOLATILE;
CREATE OR REPLACE FUNCTION ts_bgw_db_scheduler_test_run(timeout INT = -1, mock_start_time INT = 0) RETURNS VOID
AS :MODULE_PATHNAME LANGUAGE C VOLATILE;
CREATE OR REPLACE FUNCTION ts_bgw_db_scheduler_test_wait_for_scheduler_finish() RETURNS VOID
AS :MODULE_PATHNAME LANGUAGE C VOLATILE;
CREATE OR REPLACE FUNCTION ts_bgw_params_create() RETURNS VOID
AS :MODULE_PATHNAME LANGUAGE C VOLATILE;
CREATE OR REPLACE FUNCTION ts_bgw_params_destroy() RETURNS VOID
AS :MODULE_PATHNAME LANGUAGE C VOLATILE;
CREATE OR REPLACE FUNCTION ts_bgw_params_reset_time(set_time BIGINT = 0, wait BOOLEAN = false) RETURNS VOID
AS :MODULE_PATHNAME LANGUAGE C VOLATILE;
\set WAIT_ON_JOB 0
\set IMMEDIATELY_SET_UNTIL 1
\set WAIT_FOR_OTHER_TO_ADVANCE 2
-- Remove any default jobs, e.g., telemetry
DELETE FROM _timescaledb_catalog.bgw_job;
TRUNCATE _timescaledb_internal.bgw_job_stat;
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
CREATE TABLE public.bgw_log(
    msg_no INT,
    mock_time BIGINT,
    application_name TEXT,
    msg TEXT
);
CREATE VIEW sorted_bgw_log AS
SELECT msg_no,
  mock_time,
  application_name,
  regexp_replace(CASE WHEN length(msg) > 80 THEN substring(msg, 1, 80) || '...' ELSE msg END,
  		 '(execution time) [0-9]+(\.[0-9]+)?', '\1 (RANDOM)', 'g') AS msg
FROM bgw_log
ORDER BY mock_time,
  application_name COLLATE "C",
  msg_no;
CREATE TABLE public.bgw_dsm_handle_store(
    handle BIGINT
);
INSERT INTO public.bgw_dsm_handle_store VALUES (0);
SELECT ts_bgw_params_create();
 ts_bgw_params_create 
----------------------
 

SELECT * FROM _timescaledb_catalog.bgw_job;
 id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | fixed_schedule | initial_start | hypertable_id | config | check_schema | check_name | timezone 
----+------------------+-------------------+-------------+-------------+--------------+-------------+-----------+-------+-----------+----------------+---------------+---------------+--------+--------------+------------+----------

SELECT * FROM timescaledb_information.job_stats;
 hypertable_schema | hypertable_name | job_id | last_run_started_at | last_successful_finish | last_run_status | job_status | last_run_duration | next_start | total_runs | total_successes | total_failures 
-------------------+-----------------+--------+---------------------+------------------------+-----------------+------------+-------------------+------------+------------+-----------------+----------------

\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
------------------------------
-- test reorder policy runs --
------------------------------
CREATE TABLE test_reorder_table(time int, chunk_id int);
SELECT create_hypertable('test_reorder_table', 'time', chunk_time_interval => 1);
        create_hypertable        
---------------------------------
 (1,public,test_reorder_table,t)

-- These inserts should create 5 different chunks
INSERT INTO test_reorder_table VALUES (1, 1);
INSERT INTO test_reorder_table VALUES (2, 2);
INSERT INTO test_reorder_table VALUES (3, 3);
INSERT INTO test_reorder_table VALUES (4, 4);
INSERT INTO test_reorder_table VALUES (5, 5);
SELECT COUNT(*) FROM _timescaledb_catalog.chunk as c, _timescaledb_catalog.hypertable as ht where c.hypertable_id = ht.id and ht.table_name='test_reorder_table';
 count 
-------
     5

SELECT count(*) FROM _timescaledb_catalog.bgw_job WHERE proc_schema = '_timescaledb_functions' AND proc_name = 'policy_reorder';
 count 
-------
     0

select add_reorder_policy('test_reorder_table', 'test_reorder_table_time_idx') as reorder_job_id \gset
SELECT count(*) FROM _timescaledb_catalog.bgw_job WHERE proc_schema = '_timescaledb_functions' AND proc_name = 'policy_reorder';
 count 
-------
     1

-- job was created
SELECT * FROM timescaledb_information.jobs WHERE job_id=:reorder_job_id;
 job_id |   application_name    | schedule_interval | max_runtime | max_retries | retry_period |      proc_schema       |   proc_name    |       owner       | scheduled | fixed_schedule |                              config                               | next_start | initial_start | hypertable_schema |  hypertable_name   |      check_schema      |      check_name      
--------+-----------------------+-------------------+-------------+-------------+--------------+------------------------+----------------+-------------------+-----------+----------------+-------------------------------------------------------------------+------------+---------------+-------------------+--------------------+------------------------+----------------------
   1000 | Reorder Policy [1000] | @ 4 days          | @ 0         |          -1 | @ 5 mins     | _timescaledb_functions | policy_reorder | default_perm_user | t         | f              | {"index_name": "test_reorder_table_time_idx", "hypertable_id": 1} |            |               | public            | test_reorder_table | _timescaledb_functions | policy_reorder_check

-- no stats
SELECT job_id, next_start, last_finish as until_next, last_run_success, total_runs, total_successes, total_failures, total_crashes
    FROM _timescaledb_internal.bgw_job_stat
    ORDER BY job_id;
 job_id | next_start | until_next | last_run_success | total_runs | total_successes | total_failures | total_crashes 
--------+------------+------------+------------------+------------+-----------------+----------------+---------------

-- nothing clustered
SELECT indexrelid::regclass, indisclustered
    FROM pg_index
    WHERE indisclustered = true ORDER BY 1;
 indexrelid | indisclustered 
------------+----------------

-- run first time
SELECT ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish(25);
 ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish 
------------------------------------------------------------
 

SELECT * FROM sorted_bgw_log;
 msg_no | mock_time | application_name |                    msg                     
--------+-----------+------------------+--------------------------------------------
      0 |         0 | DB Scheduler     | [TESTING] Registered new background worker
      1 |         0 | DB Scheduler     | [TESTING] Wait until 25000, started at 0

SELECT * FROM timescaledb_information.jobs WHERE job_id=:reorder_job_id;
 job_id |   application_name    | schedule_interval | max_runtime | max_retries | retry_period |      proc_schema       |   proc_name    |       owner       | scheduled | fixed_schedule |                              config                               |          next_start          | initial_start | hypertable_schema |  hypertable_name   |      check_schema      |      check_name      
--------+-----------------------+-------------------+-------------+-------------+--------------+------------------------+----------------+-------------------+-----------+----------------+-------------------------------------------------------------------+------------------------------+---------------+-------------------+--------------------+------------------------+----------------------
   1000 | Reorder Policy [1000] | @ 4 days          | @ 0         |          -1 | @ 5 mins     | _timescaledb_functions | policy_reorder | default_perm_user | t         | f              | {"index_name": "test_reorder_table_time_idx", "hypertable_id": 1} | Fri Dec 31 16:00:00 1999 PST |               | public            | test_reorder_table | _timescaledb_functions | policy_reorder_check

-- job ran once, successfully
SELECT job_id, next_start, last_finish as until_next, last_run_success, total_runs, total_successes, total_failures, total_crashes
    FROM _timescaledb_internal.bgw_job_stat
    where job_id=:reorder_job_id;
 job_id |          next_start          |          until_next          | last_run_success | total_runs | total_successes | total_failures | total_crashes 
--------+------------------------------+------------------------------+------------------+------------+-----------------+----------------+---------------
   1000 | Fri Dec 31 16:00:00 1999 PST | Fri Dec 31 16:00:00 1999 PST | t                |          1 |               1 |              0 |             0

-- first chunk reordered
SELECT indexrelid::regclass, indisclustered
    FROM pg_index
    WHERE indisclustered = true ORDER BY 1;
                             indexrelid                             | indisclustered 
--------------------------------------------------------------------+----------------
 _timescaledb_internal._hyper_1_1_chunk_test_reorder_table_time_idx | t

-- second call to scheduler should immediately run reorder again, due to catchup
SELECT ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish(25);
 ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish 
------------------------------------------------------------
 

SELECT * FROM sorted_bgw_log;
 msg_no | mock_time | application_name |                     msg                      
--------+-----------+------------------+----------------------------------------------
      0 |         0 | DB Scheduler     | [TESTING] Registered new background worker
      1 |         0 | DB Scheduler     | [TESTING] Wait until 25000, started at 0
      0 |     25000 | DB Scheduler     | [TESTING] Registered new background worker
      1 |     25000 | DB Scheduler     | [TESTING] Wait until 50000, started at 25000

SELECT * FROM timescaledb_information.jobs WHERE job_id=:reorder_job_id;
 job_id |   application_name    | schedule_interval | max_runtime | max_retries | retry_period |      proc_schema       |   proc_name    |       owner       | scheduled | fixed_schedule |                              config                               |            next_start            | initial_start | hypertable_schema |  hypertable_name   |      check_schema      |      check_name      
--------+-----------------------+-------------------+-------------+-------------+--------------+------------------------+----------------+-------------------+-----------+----------------+-------------------------------------------------------------------+----------------------------------+---------------+-------------------+--------------------+------------------------+----------------------
   1000 | Reorder Policy [1000] | @ 4 days          | @ 0         |          -1 | @ 5 mins     | _timescaledb_functions | policy_reorder | default_perm_user | t         | f              | {"index_name": "test_reorder_table_time_idx", "hypertable_id": 1} | Fri Dec 31 16:00:00.025 1999 PST |               | public            | test_reorder_table | _timescaledb_functions | policy_reorder_check

-- two runs
SELECT job_id, next_start, last_finish as until_next, last_run_success, total_runs, total_successes, total_failures, total_crashes
    FROM _timescaledb_internal.bgw_job_stat
    where job_id=:reorder_job_id;
 job_id |            next_start            |            until_next            | last_run_success | total_runs | total_successes | total_failures | total_crashes 
--------+----------------------------------+----------------------------------+------------------+------------+-----------------+----------------+---------------
   1000 | Fri Dec 31 16:00:00.025 1999 PST | Fri Dec 31 16:00:00.025 1999 PST | t                |          2 |               2 |              0 |             0

-- two chunks clustered
SELECT indexrelid::regclass, indisclustered
    FROM pg_index
    WHERE indisclustered = true ORDER BY 1;
                             indexrelid                             | indisclustered 
--------------------------------------------------------------------+----------------
 _timescaledb_internal._hyper_1_1_chunk_test_reorder_table_time_idx | t
 _timescaledb_internal._hyper_1_2_chunk_test_reorder_table_time_idx | t

-- third call to scheduler should immediately run reorder again, due to catchup
SELECT ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish(50);
 ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish 
------------------------------------------------------------
 

-- job info is gone
SELECT * FROM sorted_bgw_log;
 msg_no | mock_time | application_name |                      msg                      
--------+-----------+------------------+-----------------------------------------------
      0 |         0 | DB Scheduler     | [TESTING] Registered new background worker
      1 |         0 | DB Scheduler     | [TESTING] Wait until 25000, started at 0
      0 |     25000 | DB Scheduler     | [TESTING] Registered new background worker
      1 |     25000 | DB Scheduler     | [TESTING] Wait until 50000, started at 25000
      0 |     50000 | DB Scheduler     | [TESTING] Registered new background worker
      1 |     50000 | DB Scheduler     | [TESTING] Wait until 100000, started at 50000

SELECT * FROM timescaledb_information.jobs WHERE job_id=:reorder_job_id;
 job_id |   application_name    | schedule_interval | max_runtime | max_retries | retry_period |      proc_schema       |   proc_name    |       owner       | scheduled | fixed_schedule |                              config                               |           next_start            | initial_start | hypertable_schema |  hypertable_name   |      check_schema      |      check_name      
--------+-----------------------+-------------------+-------------+-------------+--------------+------------------------+----------------+-------------------+-----------+----------------+-------------------------------------------------------------------+---------------------------------+---------------+-------------------+--------------------+------------------------+----------------------
   1000 | Reorder Policy [1000] | @ 4 days          | @ 0         |          -1 | @ 5 mins     | _timescaledb_functions | policy_reorder | default_perm_user | t         | f              | {"index_name": "test_reorder_table_time_idx", "hypertable_id": 1} | Tue Jan 04 16:00:00.05 2000 PST |               | public            | test_reorder_table | _timescaledb_functions | policy_reorder_check

SELECT *
    FROM _timescaledb_internal.bgw_job_stat
    where job_id=:reorder_job_id;
 job_id |           last_start            |           last_finish           |           next_start            |     last_successful_finish      | last_run_success | total_runs | total_duration | total_duration_failures | total_successes | total_failures | total_crashes | consecutive_failures | consecutive_crashes | flags 
--------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+------------------+------------+----------------+-------------------------+-----------------+----------------+---------------+----------------------+---------------------+-------
   1000 | Fri Dec 31 16:00:00.05 1999 PST | Fri Dec 31 16:00:00.05 1999 PST | Tue Jan 04 16:00:00.05 2000 PST | Fri Dec 31 16:00:00.05 1999 PST | t                |          3 | @ 0            | @ 0                     |               3 |              0 |             0 |                    0 |                   0 |     0

-- three chunks clustered
SELECT indexrelid::regclass, indisclustered
    FROM pg_index
    WHERE indisclustered = true ORDER BY 1;
                             indexrelid                             | indisclustered 
--------------------------------------------------------------------+----------------
 _timescaledb_internal._hyper_1_1_chunk_test_reorder_table_time_idx | t
 _timescaledb_internal._hyper_1_2_chunk_test_reorder_table_time_idx | t
 _timescaledb_internal._hyper_1_3_chunk_test_reorder_table_time_idx | t

-- running is a nop
SELECT ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish(100);
 ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish 
------------------------------------------------------------
 

SELECT * FROM sorted_bgw_log;
 msg_no | mock_time | application_name |                      msg                       
--------+-----------+------------------+------------------------------------------------
      0 |         0 | DB Scheduler     | [TESTING] Registered new background worker
      1 |         0 | DB Scheduler     | [TESTING] Wait until 25000, started at 0
      0 |     25000 | DB Scheduler     | [TESTING] Registered new background worker
      1 |     25000 | DB Scheduler     | [TESTING] Wait until 50000, started at 25000
      0 |     50000 | DB Scheduler     | [TESTING] Registered new background worker
      1 |     50000 | DB Scheduler     | [TESTING] Wait until 100000, started at 50000
      0 |    100000 | DB Scheduler     | [TESTING] Wait until 200000, started at 100000

SELECT * FROM timescaledb_information.jobs WHERE job_id=:reorder_job_id;
 job_id |   application_name    | schedule_interval | max_runtime | max_retries | retry_period |      proc_schema       |   proc_name    |       owner       | scheduled | fixed_schedule |                              config                               |           next_start            | initial_start | hypertable_schema |  hypertable_name   |      check_schema      |      check_name      
--------+-----------------------+-------------------+-------------+-------------+--------------+------------------------+----------------+-------------------+-----------+----------------+-------------------------------------------------------------------+---------------------------------+---------------+-------------------+--------------------+------------------------+----------------------
   1000 | Reorder Policy [1000] | @ 4 days          | @ 0         |          -1 | @ 5 mins     | _timescaledb_functions | policy_reorder | default_perm_user | t         | f              | {"index_name": "test_reorder_table_time_idx", "hypertable_id": 1} | Tue Jan 04 16:00:00.05 2000 PST |               | public            | test_reorder_table | _timescaledb_functions | policy_reorder_check

SELECT *
    FROM _timescaledb_internal.bgw_job_stat
    where job_id=:reorder_job_id;
 job_id |           last_start            |           last_finish           |           next_start            |     last_successful_finish      | last_run_success | total_runs | total_duration | total_duration_failures | total_successes | total_failures | total_crashes | consecutive_failures | consecutive_crashes | flags 
--------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+------------------+------------+----------------+-------------------------+-----------------+----------------+---------------+----------------------+---------------------+-------
   1000 | Fri Dec 31 16:00:00.05 1999 PST | Fri Dec 31 16:00:00.05 1999 PST | Tue Jan 04 16:00:00.05 2000 PST | Fri Dec 31 16:00:00.05 1999 PST | t                |          3 | @ 0            | @ 0                     |               3 |              0 |             0 |                    0 |                   0 |     0

-- still have 3 chunks clustered
SELECT indexrelid::regclass, indisclustered
    FROM pg_index
    WHERE indisclustered = true ORDER BY 1;
                             indexrelid                             | indisclustered 
--------------------------------------------------------------------+----------------
 _timescaledb_internal._hyper_1_1_chunk_test_reorder_table_time_idx | t
 _timescaledb_internal._hyper_1_2_chunk_test_reorder_table_time_idx | t
 _timescaledb_internal._hyper_1_3_chunk_test_reorder_table_time_idx | t

--check that views work correctly
SELECT * FROM timescaledb_information.job_stats;
 hypertable_schema |  hypertable_name   | job_id |       last_run_started_at       |     last_successful_finish      | last_run_status | job_status | last_run_duration |           next_start            | total_runs | total_successes | total_failures 
-------------------+--------------------+--------+---------------------------------+---------------------------------+-----------------+------------+-------------------+---------------------------------+------------+-----------------+----------------
 public            | test_reorder_table |   1000 | Fri Dec 31 16:00:00.05 1999 PST | Fri Dec 31 16:00:00.05 1999 PST | Success         | Scheduled  |                   | Tue Jan 04 16:00:00.05 2000 PST |          3 |               3 |              0

-- test deleting the policy
SELECT remove_reorder_policy('test_reorder_table');
 remove_reorder_policy 
-----------------------
 

SELECT * FROM timescaledb_information.jobs WHERE job_id=:reorder_job_id;
 job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | fixed_schedule | config | next_start | initial_start | hypertable_schema | hypertable_name | check_schema | check_name 
--------+------------------+-------------------+-------------+-------------+--------------+-------------+-----------+-------+-----------+----------------+--------+------------+---------------+-------------------+-----------------+--------------+------------

SELECT job_id, next_start, last_finish as until_next, last_run_success, total_runs, total_successes, total_failures, total_crashes
    FROM _timescaledb_internal.bgw_job_stat
    where job_id=:reorder_job_id;
 job_id | next_start | until_next | last_run_success | total_runs | total_successes | total_failures | total_crashes 
--------+------------+------------+------------------+------------+-----------------+----------------+---------------

SELECT ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish(125);
 ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish 
------------------------------------------------------------
 

SELECT * FROM sorted_bgw_log;
 msg_no | mock_time | application_name |                      msg                       
--------+-----------+------------------+------------------------------------------------
      0 |         0 | DB Scheduler     | [TESTING] Registered new background worker
      1 |         0 | DB Scheduler     | [TESTING] Wait until 25000, started at 0
      0 |     25000 | DB Scheduler     | [TESTING] Registered new background worker
      1 |     25000 | DB Scheduler     | [TESTING] Wait until 50000, started at 25000
      0 |     50000 | DB Scheduler     | [TESTING] Registered new background worker
      1 |     50000 | DB Scheduler     | [TESTING] Wait until 100000, started at 50000
      0 |    100000 | DB Scheduler     | [TESTING] Wait until 200000, started at 100000
      0 |    200000 | DB Scheduler     | [TESTING] Wait until 325000, started at 200000

SELECT * FROM timescaledb_information.jobs WHERE job_id=:reorder_job_id;
 job_id | application_name | schedule_interval | max_runtime | max_retries | retry_period | proc_schema | proc_name | owner | scheduled | fixed_schedule | config | next_start | initial_start | hypertable_schema | hypertable_name | check_schema | check_name 
--------+------------------+-------------------+-------------+-------------+--------------+-------------+-----------+-------+-----------+----------------+--------+------------+---------------+-------------------+-----------------+--------------+------------

-- still only 3 chunks clustered
SELECT indexrelid::regclass, indisclustered
    FROM pg_index
    WHERE indisclustered = true ORDER BY 1;
                             indexrelid                             | indisclustered 
--------------------------------------------------------------------+----------------
 _timescaledb_internal._hyper_1_1_chunk_test_reorder_table_time_idx | t
 _timescaledb_internal._hyper_1_2_chunk_test_reorder_table_time_idx | t
 _timescaledb_internal._hyper_1_3_chunk_test_reorder_table_time_idx | t

\c :TEST_DBNAME :ROLE_SUPERUSER
TRUNCATE bgw_log;
TRUNCATE _timescaledb_internal.bgw_job_stat;
DELETE FROM _timescaledb_catalog.bgw_job;
SELECT ts_bgw_params_reset_time();
 ts_bgw_params_reset_time 
--------------------------
 

\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
-----------------------------------
-- test drop chunks policy runs --
-----------------------------------
CREATE TABLE test_drop_chunks_table(time timestamptz, drop_order int);
SELECT create_hypertable('test_drop_chunks_table', 'time', chunk_time_interval => INTERVAL '1 week');
          create_hypertable          
-------------------------------------
 (2,public,test_drop_chunks_table,t)

-- These inserts should create 5 different chunks
INSERT INTO test_drop_chunks_table VALUES (now() - INTERVAL '2 month',  4);
INSERT INTO test_drop_chunks_table VALUES (now(),                       5);
INSERT INTO test_drop_chunks_table VALUES (now() - INTERVAL '6 months', 2);
INSERT INTO test_drop_chunks_table VALUES (now() - INTERVAL '4 months', 3);
INSERT INTO test_drop_chunks_table VALUES (now() - INTERVAL '8 months', 1);
SELECT show_chunks('test_drop_chunks_table');
               show_chunks               
-----------------------------------------
 _timescaledb_internal._hyper_2_6_chunk
 _timescaledb_internal._hyper_2_7_chunk
 _timescaledb_internal._hyper_2_8_chunk
 _timescaledb_internal._hyper_2_9_chunk
 _timescaledb_internal._hyper_2_10_chunk

SELECT COUNT(*) FROM _timescaledb_catalog.chunk as c, _timescaledb_catalog.hypertable as ht where c.hypertable_id = ht.id and ht.table_name='test_drop_chunks_table';
 count 
-------
     5

SELECT count(*) FROM _timescaledb_catalog.bgw_job WHERE proc_schema = '_timescaledb_functions' AND proc_name = 'policy_retention';
 count 
-------
     0

SELECT add_retention_policy('test_drop_chunks_table', INTERVAL '4 months') as drop_chunks_job_id \gset
SELECT count(*) FROM _timescaledb_catalog.bgw_job WHERE proc_schema = '_timescaledb_functions' AND proc_name = 'policy_retention';
 count 
-------
     1

SELECT alter_job(:drop_chunks_job_id, schedule_interval => INTERVAL '1 second');
                                                                                        alter_job                                                                                         
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 (1001,"@ 1 sec","@ 5 mins",-1,"@ 5 mins",t,"{""drop_after"": ""@ 4 mons"", ""hypertable_id"": 2}",-infinity,_timescaledb_functions.policy_retention_check,f,,,"Retention Policy [1001]")

SELECT * FROM timescaledb_information.jobs WHERE job_id=:drop_chunks_job_id;
 job_id |    application_name     | schedule_interval | max_runtime | max_retries | retry_period |      proc_schema       |    proc_name     |       owner       | scheduled | fixed_schedule |                     config                     | next_start | initial_start | hypertable_schema |    hypertable_name     |      check_schema      |       check_name       
--------+-------------------------+-------------------+-------------+-------------+--------------+------------------------+------------------+-------------------+-----------+----------------+------------------------------------------------+------------+---------------+-------------------+------------------------+------------------------+------------------------
   1001 | Retention Policy [1001] | @ 1 sec           | @ 5 mins    |          -1 | @ 5 mins     | _timescaledb_functions | policy_retention | default_perm_user | t         | f              | {"drop_after": "@ 4 mons", "hypertable_id": 2} |            |               | public            | test_drop_chunks_table | _timescaledb_functions | policy_retention_check

-- no stats
SELECT job_id, next_start, last_finish as until_next, last_run_success, total_runs, total_successes, total_failures, total_crashes
    FROM _timescaledb_internal.bgw_job_stat
    WHERE job_id=:drop_chunks_job_id;
 job_id | next_start | until_next | last_run_success | total_runs | total_successes | total_failures | total_crashes 
--------+------------+------------+------------------+------------+-----------------+----------------+---------------

-- all chunks are there
SELECT show_chunks('test_drop_chunks_table');
               show_chunks               
-----------------------------------------
 _timescaledb_internal._hyper_2_6_chunk
 _timescaledb_internal._hyper_2_7_chunk
 _timescaledb_internal._hyper_2_8_chunk
 _timescaledb_internal._hyper_2_9_chunk
 _timescaledb_internal._hyper_2_10_chunk

-- run first time
SELECT ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish(25);
 ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish 
------------------------------------------------------------
 

SELECT * FROM sorted_bgw_log;
 msg_no | mock_time | application_name |                    msg                     
--------+-----------+------------------+--------------------------------------------
      0 |         0 | DB Scheduler     | [TESTING] Registered new background worker
      1 |         0 | DB Scheduler     | [TESTING] Wait until 25000, started at 0

SELECT * FROM timescaledb_information.jobs WHERE job_id=:drop_chunks_job_id;
 job_id |    application_name     | schedule_interval | max_runtime | max_retries | retry_period |      proc_schema       |    proc_name     |       owner       | scheduled | fixed_schedule |                     config                     |          next_start          | initial_start | hypertable_schema |    hypertable_name     |      check_schema      |       check_name       
--------+-------------------------+-------------------+-------------+-------------+--------------+------------------------+------------------+-------------------+-----------+----------------+------------------------------------------------+------------------------------+---------------+-------------------+------------------------+------------------------+------------------------
   1001 | Retention Policy [1001] | @ 1 sec           | @ 5 mins    |          -1 | @ 5 mins     | _timescaledb_functions | policy_retention | default_perm_user | t         | f              | {"drop_after": "@ 4 mons", "hypertable_id": 2} | Fri Dec 31 16:00:01 1999 PST |               | public            | test_drop_chunks_table | _timescaledb_functions | policy_retention_check

-- job ran once, successfully
SELECT job_id, time_bucket('1m',next_start) AS next_start, time_bucket('1m',last_finish) as until_next, last_run_success, total_runs, total_successes, total_failures, total_crashes
    FROM _timescaledb_internal.bgw_job_stat
    where job_id=:drop_chunks_job_id;
 job_id |          next_start          |          until_next          | last_run_success | total_runs | total_successes | total_failures | total_crashes 
--------+------------------------------+------------------------------+------------------+------------+-----------------+----------------+---------------
   1001 | Fri Dec 31 16:00:00 1999 PST | Fri Dec 31 16:00:00 1999 PST | t                |          1 |               1 |              0 |             0

-- chunks 8 and 10 dropped
SELECT show_chunks('test_drop_chunks_table');
              show_chunks               
----------------------------------------
 _timescaledb_internal._hyper_2_6_chunk
 _timescaledb_internal._hyper_2_7_chunk
 _timescaledb_internal._hyper_2_9_chunk

-- job doesn't run again immediately
SELECT ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish(25);
 ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish 
------------------------------------------------------------
 

SELECT * FROM sorted_bgw_log;
 msg_no | mock_time | application_name |                     msg                      
--------+-----------+------------------+----------------------------------------------
      0 |         0 | DB Scheduler     | [TESTING] Registered new background worker
      1 |         0 | DB Scheduler     | [TESTING] Wait until 25000, started at 0
      0 |     25000 | DB Scheduler     | [TESTING] Wait until 50000, started at 25000

SELECT * FROM timescaledb_information.jobs WHERE job_id=:drop_chunks_job_id;
 job_id |    application_name     | schedule_interval | max_runtime | max_retries | retry_period |      proc_schema       |    proc_name     |       owner       | scheduled | fixed_schedule |                     config                     |          next_start          | initial_start | hypertable_schema |    hypertable_name     |      check_schema      |       check_name       
--------+-------------------------+-------------------+-------------+-------------+--------------+------------------------+------------------+-------------------+-----------+----------------+------------------------------------------------+------------------------------+---------------+-------------------+------------------------+------------------------+------------------------
   1001 | Retention Policy [1001] | @ 1 sec           | @ 5 mins    |          -1 | @ 5 mins     | _timescaledb_functions | policy_retention | default_perm_user | t         | f              | {"drop_after": "@ 4 mons", "hypertable_id": 2} | Fri Dec 31 16:00:01 1999 PST |               | public            | test_drop_chunks_table | _timescaledb_functions | policy_retention_check

-- still only 1 run
SELECT job_id, time_bucket('1m',next_start) AS next_start, time_bucket('1m',last_finish) as until_next, last_run_success, total_runs, total_successes, total_failures, total_crashes
    FROM _timescaledb_internal.bgw_job_stat
    where job_id=:drop_chunks_job_id;
 job_id |          next_start          |          until_next          | last_run_success | total_runs | total_successes | total_failures | total_crashes 
--------+------------------------------+------------------------------+------------------+------------+-----------------+----------------+---------------
   1001 | Fri Dec 31 16:00:00 1999 PST | Fri Dec 31 16:00:00 1999 PST | t                |          1 |               1 |              0 |             0

-- same chunks
SELECT show_chunks('test_drop_chunks_table');
              show_chunks               
----------------------------------------
 _timescaledb_internal._hyper_2_6_chunk
 _timescaledb_internal._hyper_2_7_chunk
 _timescaledb_internal._hyper_2_9_chunk

-- a new chunk older than the drop date will be dropped
INSERT INTO test_drop_chunks_table VALUES (now() - INTERVAL '12 months', 0);
SELECT show_chunks('test_drop_chunks_table');
               show_chunks               
-----------------------------------------
 _timescaledb_internal._hyper_2_6_chunk
 _timescaledb_internal._hyper_2_7_chunk
 _timescaledb_internal._hyper_2_9_chunk
 _timescaledb_internal._hyper_2_11_chunk

SELECT ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish(10000);
 ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish 
------------------------------------------------------------
 

SELECT * FROM sorted_bgw_log;
 msg_no | mock_time | application_name |                        msg                        
--------+-----------+------------------+---------------------------------------------------
      0 |         0 | DB Scheduler     | [TESTING] Registered new background worker
      1 |         0 | DB Scheduler     | [TESTING] Wait until 25000, started at 0
      0 |     25000 | DB Scheduler     | [TESTING] Wait until 50000, started at 25000
      0 |     50000 | DB Scheduler     | [TESTING] Wait until 1000000, started at 50000
      1 |   1000000 | DB Scheduler     | [TESTING] Registered new background worker
      2 |   1000000 | DB Scheduler     | [TESTING] Wait until 10050000, started at 1000000

SELECT * FROM timescaledb_information.jobs WHERE job_id=:drop_chunks_job_id;
 job_id |    application_name     | schedule_interval | max_runtime | max_retries | retry_period |      proc_schema       |    proc_name     |       owner       | scheduled | fixed_schedule |                     config                     |          next_start          | initial_start | hypertable_schema |    hypertable_name     |      check_schema      |       check_name       
--------+-------------------------+-------------------+-------------+-------------+--------------+------------------------+------------------+-------------------+-----------+----------------+------------------------------------------------+------------------------------+---------------+-------------------+------------------------+------------------------+------------------------
   1001 | Retention Policy [1001] | @ 1 sec           | @ 5 mins    |          -1 | @ 5 mins     | _timescaledb_functions | policy_retention | default_perm_user | t         | f              | {"drop_after": "@ 4 mons", "hypertable_id": 2} | Fri Dec 31 16:00:02 1999 PST |               | public            | test_drop_chunks_table | _timescaledb_functions | policy_retention_check

-- 2 runs
SELECT job_id, time_bucket('1m',next_start) AS next_start, time_bucket('1m',last_finish) as until_next, last_run_success, total_runs, total_successes, total_failures, total_crashes
    FROM _timescaledb_internal.bgw_job_stat
    where job_id=:drop_chunks_job_id;
 job_id |          next_start          |          until_next          | last_run_success | total_runs | total_successes | total_failures | total_crashes 
--------+------------------------------+------------------------------+------------------+------------+-----------------+----------------+---------------
   1001 | Fri Dec 31 16:00:00 1999 PST | Fri Dec 31 16:00:00 1999 PST | t                |          2 |               2 |              0 |             0

SELECT show_chunks('test_drop_chunks_table');
              show_chunks               
----------------------------------------
 _timescaledb_internal._hyper_2_6_chunk
 _timescaledb_internal._hyper_2_7_chunk
 _timescaledb_internal._hyper_2_9_chunk

--test that views work
SELECT * FROM timescaledb_information.job_stats;
 hypertable_schema |    hypertable_name     | job_id |     last_run_started_at      |    last_successful_finish    | last_run_status | job_status | last_run_duration |          next_start          | total_runs | total_successes | total_failures 
-------------------+------------------------+--------+------------------------------+------------------------------+-----------------+------------+-------------------+------------------------------+------------+-----------------+----------------
 public            | test_drop_chunks_table |   1001 | Fri Dec 31 16:00:01 1999 PST | Fri Dec 31 16:00:01 1999 PST | Success         | Scheduled  |                   | Fri Dec 31 16:00:02 1999 PST |          2 |               2 |              0

-- Test that add_retention_policy also works with timestamp (without time zone) and date types
-- and that the policy execution is being logged
-- Test for date
CREATE TABLE test_drop_chunks_table_date(time date, drop_order int);
SELECT create_hypertable('test_drop_chunks_table_date', 'time', chunk_time_interval => INTERVAL '1 week');
            create_hypertable             
------------------------------------------
 (3,public,test_drop_chunks_table_date,t)

INSERT INTO test_drop_chunks_table_date VALUES (now() - INTERVAL '2 month',  4);
INSERT INTO test_drop_chunks_table_date VALUES (now(),                       5);
INSERT INTO test_drop_chunks_table_date VALUES (now() - INTERVAL '6 months', 2);
INSERT INTO test_drop_chunks_table_date VALUES (now() - INTERVAL '4 months', 3);
INSERT INTO test_drop_chunks_table_date VALUES (now() - INTERVAL '8 months', 1);
-- Clear the job stats and reset timer, this will also clear the bgw_log
\c :TEST_DBNAME :ROLE_SUPERUSER
TRUNCATE bgw_log;
TRUNCATE _timescaledb_internal.bgw_job_stat;
DELETE FROM _timescaledb_catalog.bgw_job;
SELECT ts_bgw_params_reset_time();
 ts_bgw_params_reset_time 
--------------------------
 

\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
-- Test for timestamp
CREATE TABLE test_drop_chunks_table_tsntz(time date, drop_order int);
SELECT create_hypertable('test_drop_chunks_table_tsntz', 'time', chunk_time_interval => INTERVAL '1 week');
             create_hypertable             
-------------------------------------------
 (4,public,test_drop_chunks_table_tsntz,t)

INSERT INTO test_drop_chunks_table_tsntz VALUES (now() - INTERVAL '2 month',  4);
INSERT INTO test_drop_chunks_table_tsntz VALUES (now(),                       5);
INSERT INTO test_drop_chunks_table_tsntz VALUES (now() - INTERVAL '6 months', 2);
INSERT INTO test_drop_chunks_table_tsntz VALUES (now() - INTERVAL '4 months', 3);
INSERT INTO test_drop_chunks_table_tsntz VALUES (now() - INTERVAL '8 months', 1);
-- Add retention policies for both tables
SELECT add_retention_policy('test_drop_chunks_table_date', INTERVAL '4 months') as drop_chunks_date_job_id \gset
SELECT add_retention_policy('test_drop_chunks_table_tsntz', INTERVAL '4 months') as drop_chunks_tsntz_job_id \gset
-- Test that retention policy is being logged
SELECT alter_job(id,config:=jsonb_set(config,'{verbose_log}', 'true'))
 FROM _timescaledb_catalog.bgw_job WHERE id = :drop_chunks_date_job_id;
                                                                                                    alter_job                                                                                                    
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 (1002,"@ 1 day","@ 5 mins",-1,"@ 5 mins",t,"{""drop_after"": ""@ 4 mons"", ""verbose_log"": true, ""hypertable_id"": 3}",-infinity,_timescaledb_functions.policy_retention_check,f,,,"Retention Policy [1002]")

SELECT alter_job(id,config:=jsonb_set(config,'{verbose_log}', 'true'))
 FROM _timescaledb_catalog.bgw_job WHERE id = :drop_chunks_tsntz_job_id;
                                                                                                    alter_job                                                                                                    
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 (1003,"@ 1 day","@ 5 mins",-1,"@ 5 mins",t,"{""drop_after"": ""@ 4 mons"", ""verbose_log"": true, ""hypertable_id"": 4}",-infinity,_timescaledb_functions.policy_retention_check,f,,,"Retention Policy [1003]")

SELECT ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish(1000);
 ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish 
------------------------------------------------------------
 

SELECT * FROM sorted_bgw_log;
 msg_no | mock_time |    application_name     |                                         msg                                         
--------+-----------+-------------------------+-------------------------------------------------------------------------------------
      0 |         0 | DB Scheduler            | [TESTING] Registered new background worker
      1 |         0 | DB Scheduler            | [TESTING] Registered new background worker
      2 |         0 | DB Scheduler            | [TESTING] Wait until 1000000, started at 0
      0 |         0 | Retention Policy [1002] | applying retention policy to hypertable "test_drop_chunks_table_date": dropping ...
      0 |         0 | Retention Policy [1003] | applying retention policy to hypertable "test_drop_chunks_table_tsntz": dropping...

-- test the schedule_interval parameter for policies
CREATE TABLE test_schedint(time timestamptz, a int, b int);
select create_hypertable('test_schedint', 'time');
     create_hypertable      
----------------------------
 (5,public,test_schedint,t)

insert into test_schedint values (now(), 1, 2), (now() + interval '2 seconds', 2, 3);
-- test the retention policy
select add_retention_policy('test_schedint', interval '2 months', schedule_interval => '30 seconds') as polret_schedint \gset
-- wait for a bit more than "schedule_interval" seconds, then verify the policy has run twice
select ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish(1000);
 ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish 
------------------------------------------------------------
 

select total_runs, total_successes, total_failures from timescaledb_information.job_stats where job_id = :polret_schedint;
 total_runs | total_successes | total_failures 
------------+-----------------+----------------
          1 |               1 |              0

select ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish(30000);
 ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish 
------------------------------------------------------------
 

select total_runs, total_successes, total_failures from timescaledb_information.job_stats where job_id = :polret_schedint;
 total_runs | total_successes | total_failures 
------------+-----------------+----------------
          2 |               2 |              0

-- if we wait another 30s, we should see 3 runs of the job
select ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish(30000);
 ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish 
------------------------------------------------------------
 

select total_runs, total_successes, total_failures from timescaledb_information.job_stats where job_id = :polret_schedint;
 total_runs | total_successes | total_failures 
------------+-----------------+----------------
          3 |               3 |              0

-- test the compression policy
alter table test_schedint set (timescaledb.compress);
select add_compression_policy('test_schedint', interval '3 weeks', schedule_interval => '40 seconds') as polcomp_schedint \gset
select ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish(1000);
 ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish 
------------------------------------------------------------
 

select total_runs, total_successes, total_failures from timescaledb_information.job_stats where job_id = :polcomp_schedint;
 total_runs | total_successes | total_failures 
------------+-----------------+----------------
          1 |               1 |              0

select ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish(40000);
 ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish 
------------------------------------------------------------
 

select total_runs, total_successes, total_failures from timescaledb_information.job_stats where job_id = :polcomp_schedint;
 total_runs | total_successes | total_failures 
------------+-----------------+----------------
          2 |               2 |              0

-- if we wait another 40s, we should see 3 runs of the job
select ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish(40000);
 ts_bgw_db_scheduler_test_run_and_wait_for_scheduler_finish 
------------------------------------------------------------
 

select total_runs, total_successes, total_failures from timescaledb_information.job_stats where job_id = :polcomp_schedint;
 total_runs | total_successes | total_failures 
------------+-----------------+----------------
          3 |               3 |              0

