-- 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
SET timescaledb.license_key='CommunityLicense';
CREATE OR REPLACE FUNCTION ts_test_chunk_stats_insert(job_id INTEGER, chunk_id INTEGER, num_times_run INTEGER, last_time_run TIMESTAMPTZ = NULL) RETURNS VOID
AS :TSL_MODULE_PATHNAME LANGUAGE C VOLATILE;
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
SELECT * FROM _timescaledb_catalog.bgw_job WHERE id >= 1000 ORDER BY id;
 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 
----+------------------+-------------------+-------------+-------------+--------------+-------------+-----------+-------+-----------+----------------+---------------+---------------+--------+--------------+------------+----------

CREATE TABLE test_table(time timestamptz, junk int);
CREATE TABLE test_table_int(time bigint, junk int);
SELECT create_hypertable('test_table', 'time');
    create_hypertable    
-------------------------
 (1,public,test_table,t)

SELECT create_hypertable('test_table_int', 'time', chunk_time_interval => 1);
      create_hypertable      
-----------------------------
 (2,public,test_table_int,t)

CREATE INDEX second_index on test_table (time);
CREATE INDEX third_index on test_table (time);
select add_reorder_policy('test_table', 'test_table_time_idx') as job_id \gset
-- Noop for duplicate policy
select add_reorder_policy('test_table', 'test_table_time_idx', true);
NOTICE:  reorder policy already exists on hypertable "test_table", skipping
 add_reorder_policy 
--------------------
                 -1

select add_reorder_policy('test_table', 'second_index', true);
WARNING:  reorder policy already exists for hypertable "test_table"
 add_reorder_policy 
--------------------
                 -1

select add_reorder_policy('test_table', 'third_index', true);
WARNING:  reorder policy already exists for hypertable "test_table"
 add_reorder_policy 
--------------------
                 -1

\set ON_ERROR_STOP 0
-- Error whenever incorrect arguments are applied (must have table and index)
select add_reorder_policy('test_table', 'bad_index');
ERROR:  invalid reorder index
select add_reorder_policy('test_table', '');
ERROR:  invalid reorder index
select add_reorder_policy('test_table');
ERROR:  function add_reorder_policy(unknown) does not exist at character 8
select add_reorder_policy('test_table', 'second_index');
ERROR:  reorder policy already exists for hypertable "test_table"
select add_reorder_policy('test_table', 'third_index');
ERROR:  reorder policy already exists for hypertable "test_table"
select add_reorder_policy(NULL, 'third_index');
 add_reorder_policy 
--------------------
                   

select add_reorder_policy(2, 'third_index');
ERROR:  OID 2 does not refer to a table
\set ON_ERROR_STOP 1
select * from _timescaledb_catalog.bgw_job where id=:job_id;
  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 
------+-----------------------+-------------------+-------------+-------------+--------------+------------------------+----------------+-------------------+-----------+----------------+---------------+---------------+-----------------------------------------------------------+------------------------+----------------------+----------
 1000 | Reorder Policy [1000] | @ 84 hours        | @ 0         |          -1 | @ 5 mins     | _timescaledb_functions | policy_reorder | default_perm_user | t         | f              |               |             1 | {"index_name": "test_table_time_idx", "hypertable_id": 1} | _timescaledb_functions | policy_reorder_check | 

-- Now check that default scheduling interval for reorder policy is calculated correctly
-- Should be 1/2 default chunk interval length
CREATE TABLE test_table2(time timestamptz, junk int);
SELECT create_hypertable('test_table2', 'time', chunk_time_interval=>INTERVAL '1 day');
    create_hypertable     
--------------------------
 (3,public,test_table2,t)

select add_reorder_policy('test_table2', 'test_table2_time_idx');
 add_reorder_policy 
--------------------
               1001

SELECT * FROM _timescaledb_catalog.bgw_job WHERE id >= 1000 ORDER BY id;
  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 
------+-----------------------+-------------------+-------------+-------------+--------------+------------------------+----------------+-------------------+-----------+----------------+---------------+---------------+------------------------------------------------------------+------------------------+----------------------+----------
 1000 | Reorder Policy [1000] | @ 84 hours        | @ 0         |          -1 | @ 5 mins     | _timescaledb_functions | policy_reorder | default_perm_user | t         | f              |               |             1 | {"index_name": "test_table_time_idx", "hypertable_id": 1}  | _timescaledb_functions | policy_reorder_check | 
 1001 | Reorder Policy [1001] | @ 12 hours        | @ 0         |          -1 | @ 5 mins     | _timescaledb_functions | policy_reorder | default_perm_user | t         | f              |               |             3 | {"index_name": "test_table2_time_idx", "hypertable_id": 3} | _timescaledb_functions | policy_reorder_check | 

DROP TABLE test_table2;
-- Make sure that test_table2 reorder policy gets dropped
SELECT * FROM _timescaledb_catalog.bgw_job WHERE id >= 1000 ORDER BY id;
  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 
------+-----------------------+-------------------+-------------+-------------+--------------+------------------------+----------------+-------------------+-----------+----------------+---------------+---------------+-----------------------------------------------------------+------------------------+----------------------+----------
 1000 | Reorder Policy [1000] | @ 84 hours        | @ 0         |          -1 | @ 5 mins     | _timescaledb_functions | policy_reorder | default_perm_user | t         | f              |               |             1 | {"index_name": "test_table_time_idx", "hypertable_id": 1} | _timescaledb_functions | policy_reorder_check | 

-- Error whenever incorrect arguments are applied (must have table and interval)
\set ON_ERROR_STOP 0
select add_retention_policy();
ERROR:  function add_retention_policy() does not exist at character 8
select add_retention_policy('test_table');
ERROR:  need to specify one of "drop_after" or "drop_created_before"
select add_retention_policy(INTERVAL '3 hours');
ERROR:  function add_retention_policy(interval) does not exist at character 8
select add_retention_policy('test_table', INTERVAL 'haha');
ERROR:  invalid input syntax for type interval: "haha" at character 52
select add_retention_policy('test_table', 'haha');
ERROR:  invalid value for parameter drop_after
select add_retention_policy('test_table', 42);
ERROR:  invalid value for parameter drop_after
select add_retention_policy('fake_table', INTERVAL '3 month');
ERROR:  relation "fake_table" does not exist at character 29
\set ON_ERROR_STOP 1
select add_retention_policy('test_table', INTERVAL '3 month', true);
 add_retention_policy 
----------------------
                 1002

-- Should not add new policy with different parameters
select add_retention_policy('test_table', INTERVAL '3 month', true);
NOTICE:  retention policy already exists for hypertable "test_table", skipping
 add_retention_policy 
----------------------
                   -1

select add_retention_policy('test_table', INTERVAL '1 year', if_not_exists => true);
WARNING:  retention policy already exists for hypertable "test_table"
 add_retention_policy 
----------------------
                   -1

select add_retention_policy('test_table', INTERVAL '3 days', if_not_exists => true);
WARNING:  retention policy already exists for hypertable "test_table"
 add_retention_policy 
----------------------
                   -1

select add_retention_policy('test_table', INTERVAL '3 days', if_not_exists => true);
WARNING:  retention policy already exists for hypertable "test_table"
 add_retention_policy 
----------------------
                   -1

SELECT * FROM _timescaledb_catalog.bgw_job WHERE proc_name = 'policy_retention' ORDER BY id;
  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 
------+-------------------------+-------------------+-------------+-------------+--------------+------------------------+------------------+-------------------+-----------+----------------+---------------+---------------+------------------------------------------------+------------------------+------------------------+----------
 1002 | Retention Policy [1002] | @ 1 day           | @ 5 mins    |          -1 | @ 5 mins     | _timescaledb_functions | policy_retention | default_perm_user | t         | f              |               |             1 | {"drop_after": "@ 3 mons", "hypertable_id": 1} | _timescaledb_functions | policy_retention_check | 

\set ON_ERROR_STOP 0
select add_retention_policy('test_table', INTERVAL '1 year');
ERROR:  retention policy already exists for hypertable "test_table"
select add_retention_policy('test_table', INTERVAL '3 days');
ERROR:  retention policy already exists for hypertable "test_table"
\set ON_ERROR_STOP 1
SELECT * FROM _timescaledb_catalog.bgw_job WHERE proc_name = 'policy_retention' ORDER BY id;
  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 
------+-------------------------+-------------------+-------------+-------------+--------------+------------------------+------------------+-------------------+-----------+----------------+---------------+---------------+------------------------------------------------+------------------------+------------------------+----------
 1002 | Retention Policy [1002] | @ 1 day           | @ 5 mins    |          -1 | @ 5 mins     | _timescaledb_functions | policy_retention | default_perm_user | t         | f              |               |             1 | {"drop_after": "@ 3 mons", "hypertable_id": 1} | _timescaledb_functions | policy_retention_check | 

select remove_retention_policy('test_table');
 remove_retention_policy 
-------------------------
 

-- Test set_integer_now_func and add_retention_policy with
-- hypertables that have integer time dimension
select * from _timescaledb_catalog.dimension;
 id | hypertable_id | column_name |       column_type        | aligned | num_slices | partitioning_func_schema | partitioning_func | interval_length | compress_interval_length | integer_now_func_schema | integer_now_func 
----+---------------+-------------+--------------------------+---------+------------+--------------------------+-------------------+-----------------+--------------------------+-------------------------+------------------
  1 |             1 | time        | timestamp with time zone | t       |            |                          |                   |    604800000000 |                          |                         | 
  2 |             2 | time        | bigint                   | t       |            |                          |                   |               1 |                          |                         | 

\c :TEST_DBNAME :ROLE_SUPERUSER
CREATE SCHEMA IF NOT EXISTS my_new_schema;
create or replace function my_new_schema.dummy_now2() returns BIGINT LANGUAGE SQL IMMUTABLE as  'SELECT 1::BIGINT';
grant usage on SCHEMA my_new_schema to public;
grant execute on ALL FUNCTIONS IN SCHEMA my_new_schema to public;
select set_integer_now_func('test_table_int', 'my_new_schema.dummy_now2');
 set_integer_now_func 
----------------------
 

\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
select * from _timescaledb_catalog.dimension;
 id | hypertable_id | column_name |       column_type        | aligned | num_slices | partitioning_func_schema | partitioning_func | interval_length | compress_interval_length | integer_now_func_schema | integer_now_func 
----+---------------+-------------+--------------------------+---------+------------+--------------------------+-------------------+-----------------+--------------------------+-------------------------+------------------
  1 |             1 | time        | timestamp with time zone | t       |            |                          |                   |    604800000000 |                          |                         | 
  2 |             2 | time        | bigint                   | t       |            |                          |                   |               1 |                          | my_new_schema           | dummy_now2

SELECT * FROM _timescaledb_catalog.bgw_job WHERE proc_name = 'policy_retention' ORDER BY id;
 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 remove_reorder_policy('test_table');
 remove_reorder_policy 
-----------------------
 

SELECT * FROM _timescaledb_catalog.bgw_job WHERE id >= 1000 ORDER BY id;
 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 add_retention_policy('test_table', INTERVAL '3 month');
 add_retention_policy 
----------------------
                 1003

SELECT * FROM _timescaledb_catalog.bgw_job WHERE id >= 1000 ORDER BY id;
  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 
------+-------------------------+-------------------+-------------+-------------+--------------+------------------------+------------------+-------------------+-----------+----------------+---------------+---------------+------------------------------------------------+------------------------+------------------------+----------
 1003 | Retention Policy [1003] | @ 1 day           | @ 5 mins    |          -1 | @ 5 mins     | _timescaledb_functions | policy_retention | default_perm_user | t         | f              |               |             1 | {"drop_after": "@ 3 mons", "hypertable_id": 1} | _timescaledb_functions | policy_retention_check | 

select remove_retention_policy('test_table');
 remove_retention_policy 
-------------------------
 

SELECT * FROM _timescaledb_catalog.bgw_job WHERE id >= 1000 ORDER BY id;
 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 add_retention_policy('test_table_int', 1);
 add_retention_policy 
----------------------
                 1004

SELECT * FROM _timescaledb_catalog.bgw_job WHERE id >= 1000 ORDER BY id;
  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 
------+-------------------------+-------------------+-------------+-------------+--------------+------------------------+------------------+-------------------+-----------+----------------+---------------+---------------+---------------------------------------+------------------------+------------------------+----------
 1004 | Retention Policy [1004] | @ 1 day           | @ 5 mins    |          -1 | @ 5 mins     | _timescaledb_functions | policy_retention | default_perm_user | t         | f              |               |             2 | {"drop_after": 1, "hypertable_id": 2} | _timescaledb_functions | policy_retention_check | 

-- Should not add new policy with different parameters
select add_retention_policy('test_table_int', 2, true);
WARNING:  retention policy already exists for hypertable "test_table_int"
 add_retention_policy 
----------------------
                   -1

select remove_retention_policy('test_table_int');
 remove_retention_policy 
-------------------------
 

SELECT * FROM _timescaledb_catalog.bgw_job WHERE id >= 1000 ORDER BY id;
 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 
----+------------------+-------------------+-------------+-------------+--------------+-------------+-----------+-------+-----------+----------------+---------------+---------------+--------+--------------+------------+----------

-- Make sure remove works when there's nothing to remove
select remove_retention_policy('test_table', true);
NOTICE:  retention policy not found for hypertable "test_table", skipping
 remove_retention_policy 
-------------------------
 

select remove_reorder_policy('test_table', true);
NOTICE:  reorder policy not found for hypertable "test_table", skipping
 remove_reorder_policy 
-----------------------
 

\set ON_ERROR_STOP 0
select remove_retention_policy();
ERROR:  function remove_retention_policy() does not exist at character 8
select remove_retention_policy('fake_table');
ERROR:  relation "fake_table" does not exist at character 32
select remove_reorder_policy();
ERROR:  function remove_reorder_policy() does not exist at character 8
select remove_reorder_policy('fake_table');
ERROR:  relation "fake_table" does not exist at character 30
\set ON_ERROR_STOP 1
\set ON_ERROR_STOP 0
-- This should be noop
select remove_reorder_policy(2, true);
ERROR:  OID 2 does not refer to a table
-- Fail with error message
select remove_reorder_policy(2);
ERROR:  OID 2 does not refer to a table
\set ON_ERROR_STOP 1
-- Now make sure policy args have correct job deletion dependency
SELECT * FROM _timescaledb_catalog.bgw_job WHERE id >= 1000 ORDER BY id;
 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 add_retention_policy('test_table', INTERVAL '2 month') as job_id \gset
select add_reorder_policy('test_table', 'third_index') as reorder_job_id \gset
select count(*) from _timescaledb_catalog.bgw_job where id=:job_id;
 count 
-------
     1

select count(*) from _timescaledb_catalog.bgw_job where id=:reorder_job_id;
 count 
-------
     1

select delete_job(:job_id);
 delete_job 
------------
 

select count(*) from _timescaledb_catalog.bgw_job where id=:job_id;
 count 
-------
     0

-- Job config should still be there
select count(*) from _timescaledb_catalog.bgw_job where id=:reorder_job_id;
 count 
-------
     1

select delete_job(:reorder_job_id);
 delete_job 
------------
 

select count(*) from _timescaledb_catalog.bgw_job where id=:reorder_job_id;
 count 
-------
     0

-- Now make sure policy args have correct job deletion dependency
select add_retention_policy('test_table', INTERVAL '2 month') as job_id \gset
select add_reorder_policy('test_table', 'third_index') as reorder_job_id \gset
select count(*) from _timescaledb_catalog.bgw_job where id=:job_id;
 count 
-------
     1

select count(*) from _timescaledb_catalog.bgw_job where id=:reorder_job_id;
 count 
-------
     1

DROP TABLE test_table;
select count(*) from _timescaledb_catalog.bgw_job where id=:job_id;
 count 
-------
     0

select count(*) from _timescaledb_catalog.bgw_job where id=:reorder_job_id;
 count 
-------
     0

-- Check that we can't add policies on non-hypertables
CREATE TABLE non_hypertable(junk int, more_junk int);
CREATE INDEX non_ht_index on non_hypertable(junk);
\set ON_ERROR_STOP 0
select add_retention_policy('non_hypertable', INTERVAL '2 month');
ERROR:  "non_hypertable" is not a hypertable or a continuous aggregate
select add_reorder_policy('non_hypertable', 'non_ht_index');
ERROR:  table "non_hypertable" is not a hypertable
\set ON_ERROR_STOP 1
-- Now make sure things work with multiple policies on multiple hypertables
CREATE TABLE test_table(time timestamptz, junk int);
SELECT create_hypertable('test_table', 'time');
    create_hypertable    
-------------------------
 (4,public,test_table,t)

CREATE INDEX second_index on test_table (time);
CREATE TABLE test_table2(time timestamptz, junk int);
SELECT create_hypertable('test_table2', 'time');
    create_hypertable     
--------------------------
 (5,public,test_table2,t)

CREATE INDEX junk_index on test_table2 (junk);
select add_retention_policy('test_table', INTERVAL '2 days');
 add_retention_policy 
----------------------
                 1009

select add_retention_policy('test_table2', INTERVAL '1 days');
 add_retention_policy 
----------------------
                 1010

SELECT * FROM _timescaledb_catalog.bgw_job WHERE id >= 1000 ORDER BY id;
  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 
------+-------------------------+-------------------+-------------+-------------+--------------+------------------------+------------------+-------------------+-----------+----------------+---------------+---------------+------------------------------------------------+------------------------+------------------------+----------
 1009 | Retention Policy [1009] | @ 1 day           | @ 5 mins    |          -1 | @ 5 mins     | _timescaledb_functions | policy_retention | default_perm_user | t         | f              |               |             4 | {"drop_after": "@ 2 days", "hypertable_id": 4} | _timescaledb_functions | policy_retention_check | 
 1010 | Retention Policy [1010] | @ 1 day           | @ 5 mins    |          -1 | @ 5 mins     | _timescaledb_functions | policy_retention | default_perm_user | t         | f              |               |             5 | {"drop_after": "@ 1 day", "hypertable_id": 5}  | _timescaledb_functions | policy_retention_check | 

DROP TABLE test_table;
DROP TABLE test_table_int;
SELECT * FROM _timescaledb_catalog.bgw_job WHERE id >= 1000 ORDER BY id;
  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 
------+-------------------------+-------------------+-------------+-------------+--------------+------------------------+------------------+-------------------+-----------+----------------+---------------+---------------+-----------------------------------------------+------------------------+------------------------+----------
 1010 | Retention Policy [1010] | @ 1 day           | @ 5 mins    |          -1 | @ 5 mins     | _timescaledb_functions | policy_retention | default_perm_user | t         | f              |               |             5 | {"drop_after": "@ 1 day", "hypertable_id": 5} | _timescaledb_functions | policy_retention_check | 

DROP TABLE test_table2;
SELECT * FROM _timescaledb_catalog.bgw_job WHERE id >= 1000 ORDER BY id;
 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 
----+------------------+-------------------+-------------+-------------+--------------+-------------+-----------+-------+-----------+----------------+---------------+---------------+--------+--------------+------------+----------

-- Now test chunk_stat insertion
select ts_test_chunk_stats_insert(123, 123, 45);
 ts_test_chunk_stats_insert 
----------------------------
 

select job_id,chunk_id,num_times_job_run from _timescaledb_internal.bgw_policy_chunk_stats;
 job_id | chunk_id | num_times_job_run 
--------+----------+-------------------
    123 |      123 |                45

\c :TEST_DBNAME :ROLE_SUPERUSER
TRUNCATE _timescaledb_internal.bgw_policy_chunk_stats;
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
-- Now test chunk_stat deletion is correct
select job_id,chunk_id,num_times_job_run from _timescaledb_internal.bgw_policy_chunk_stats;
 job_id | chunk_id | num_times_job_run 
--------+----------+-------------------

CREATE TABLE test_table(time timestamptz, junk int);
SELECT create_hypertable('test_table', 'time');
    create_hypertable    
-------------------------
 (6,public,test_table,t)

CREATE INDEX second_index on test_table (time);
insert into test_table values (now(), 1);
insert into test_table values (now() - INTERVAL '5 weeks', 123);
select c.id from _timescaledb_catalog.chunk as c, _timescaledb_catalog.hypertable as h where c.hypertable_id=h.id and h.table_name='test_table' ORDER BY c.id;
 id 
----
  1
  2

select c.id as chunk_id from _timescaledb_catalog.chunk as c, _timescaledb_catalog.hypertable as h where c.hypertable_id=h.id and h.table_name='test_table' ORDER BY c.id LIMIT 1 \gset
select add_reorder_policy('test_table', 'second_index') as job_id \gset
-- Simulate reorder job running and setting this stat row
select ts_test_chunk_stats_insert(:job_id, :chunk_id, 1);
 ts_test_chunk_stats_insert 
----------------------------
 

select job_id,chunk_id,num_times_job_run from _timescaledb_internal.bgw_policy_chunk_stats;
 job_id | chunk_id | num_times_job_run 
--------+----------+-------------------
   1011 |        1 |                 1

SELECT * FROM _timescaledb_catalog.bgw_job WHERE id >= 1000 ORDER BY id;
  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 
------+-----------------------+-------------------+-------------+-------------+--------------+------------------------+----------------+-------------------+-----------+----------------+---------------+---------------+----------------------------------------------------+------------------------+----------------------+----------
 1011 | Reorder Policy [1011] | @ 84 hours        | @ 0         |          -1 | @ 5 mins     | _timescaledb_functions | policy_reorder | default_perm_user | t         | f              |               |             6 | {"index_name": "second_index", "hypertable_id": 6} | _timescaledb_functions | policy_reorder_check | 

-- Deleting a chunk that has nothing to do with the job should do nothing
select c.table_name as other_chunk_name,c.schema_name as other_chunk_schema from _timescaledb_catalog.chunk as c, _timescaledb_catalog.hypertable as h where c.id != :chunk_id \gset
select concat(:'other_chunk_schema','.',:'other_chunk_name') as other_chunk \gset
DROP TABLE :other_chunk;
select job_id,chunk_id,num_times_job_run from _timescaledb_internal.bgw_policy_chunk_stats;
 job_id | chunk_id | num_times_job_run 
--------+----------+-------------------
   1011 |        1 |                 1

SELECT * FROM _timescaledb_catalog.bgw_job WHERE id >= 1000 ORDER BY id;
  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 
------+-----------------------+-------------------+-------------+-------------+--------------+------------------------+----------------+-------------------+-----------+----------------+---------------+---------------+----------------------------------------------------+------------------------+----------------------+----------
 1011 | Reorder Policy [1011] | @ 84 hours        | @ 0         |          -1 | @ 5 mins     | _timescaledb_functions | policy_reorder | default_perm_user | t         | f              |               |             6 | {"index_name": "second_index", "hypertable_id": 6} | _timescaledb_functions | policy_reorder_check | 

-- Dropping the hypertable should drop the chunk, which should drop the reorder policy
DROP TABLE test_table;
select job_id,chunk_id,num_times_job_run from _timescaledb_internal.bgw_policy_chunk_stats;
 job_id | chunk_id | num_times_job_run 
--------+----------+-------------------

SELECT * FROM _timescaledb_catalog.bgw_job WHERE id >= 1000 ORDER BY id;
 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 
----+------------------+-------------------+-------------+-------------+--------------+-------------+-----------+-------+-----------+----------------+---------------+---------------+--------+--------------+------------+----------

-- Now check dropping a job will drop the chunk_stat row
CREATE TABLE test_table(time timestamptz, junk int);
SELECT create_hypertable('test_table', 'time');
    create_hypertable    
-------------------------
 (7,public,test_table,t)

select add_reorder_policy('test_table', 'test_table_time_idx') as job_id \gset
select add_retention_policy('test_table', INTERVAL '2 days', true);
 add_retention_policy 
----------------------
                 1013

select ts_test_chunk_stats_insert(:job_id, 123, 1);
 ts_test_chunk_stats_insert 
----------------------------
 

select job_id,chunk_id,num_times_job_run from _timescaledb_internal.bgw_policy_chunk_stats;
 job_id | chunk_id | num_times_job_run 
--------+----------+-------------------
   1012 |      123 |                 1

SELECT * FROM _timescaledb_catalog.bgw_job WHERE id >= 1000 ORDER BY id;
  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 
------+-------------------------+-------------------+-------------+-------------+--------------+------------------------+------------------+-------------------+-----------+----------------+---------------+---------------+-----------------------------------------------------------+------------------------+------------------------+----------
 1012 | Reorder Policy [1012]   | @ 84 hours        | @ 0         |          -1 | @ 5 mins     | _timescaledb_functions | policy_reorder   | default_perm_user | t         | f              |               |             7 | {"index_name": "test_table_time_idx", "hypertable_id": 7} | _timescaledb_functions | policy_reorder_check   | 
 1013 | Retention Policy [1013] | @ 1 day           | @ 5 mins    |          -1 | @ 5 mins     | _timescaledb_functions | policy_retention | default_perm_user | t         | f              |               |             7 | {"drop_after": "@ 2 days", "hypertable_id": 7}            | _timescaledb_functions | policy_retention_check | 

-- Dropping the drop_chunks job should not affect the chunk_stats row
select remove_retention_policy('test_table');
 remove_retention_policy 
-------------------------
 

select job_id,chunk_id,num_times_job_run from _timescaledb_internal.bgw_policy_chunk_stats;
 job_id | chunk_id | num_times_job_run 
--------+----------+-------------------
   1012 |      123 |                 1

SELECT * FROM _timescaledb_catalog.bgw_job WHERE id >= 1000 ORDER BY id;
  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 
------+-----------------------+-------------------+-------------+-------------+--------------+------------------------+----------------+-------------------+-----------+----------------+---------------+---------------+-----------------------------------------------------------+------------------------+----------------------+----------
 1012 | Reorder Policy [1012] | @ 84 hours        | @ 0         |          -1 | @ 5 mins     | _timescaledb_functions | policy_reorder | default_perm_user | t         | f              |               |             7 | {"index_name": "test_table_time_idx", "hypertable_id": 7} | _timescaledb_functions | policy_reorder_check | 

select remove_reorder_policy('test_table');
 remove_reorder_policy 
-----------------------
 

-- Row should be gone
select job_id,chunk_id,num_times_job_run from _timescaledb_internal.bgw_policy_chunk_stats;
 job_id | chunk_id | num_times_job_run 
--------+----------+-------------------

SELECT * FROM _timescaledb_catalog.bgw_job WHERE id >= 1000 ORDER BY id;
 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 
----+------------------+-------------------+-------------+-------------+--------------+-------------+-----------+-------+-----------+----------------+---------------+---------------+--------+--------------+------------+----------

-- Now test if alter_job works
select add_reorder_policy('test_table', 'test_table_time_idx') as job_id \gset
 select * from _timescaledb_catalog.bgw_job where id=:job_id;
  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 
------+-----------------------+-------------------+-------------+-------------+--------------+------------------------+----------------+-------------------+-----------+----------------+---------------+---------------+-----------------------------------------------------------+------------------------+----------------------+----------
 1014 | Reorder Policy [1014] | @ 84 hours        | @ 0         |          -1 | @ 5 mins     | _timescaledb_functions | policy_reorder | default_perm_user | t         | f              |               |             7 | {"index_name": "test_table_time_idx", "hypertable_id": 7} | _timescaledb_functions | policy_reorder_check | 

-- No change
select * from alter_job(:job_id);
 job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled |                          config                           | next_start |                check_config                 | fixed_schedule | initial_start | timezone |   application_name    
--------+-------------------+-------------+-------------+--------------+-----------+-----------------------------------------------------------+------------+---------------------------------------------+----------------+---------------+----------+-----------------------
   1014 | @ 84 hours        | @ 0         |          -1 | @ 5 mins     | t         | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity  | _timescaledb_functions.policy_reorder_check | f              |               |          | Reorder Policy [1014]

-- Changes expected
select * from alter_job(:job_id, INTERVAL '3 years', INTERVAL '5 min', 5, INTERVAL '123 sec');
 job_id | schedule_interval | max_runtime | max_retries |  retry_period   | scheduled |                          config                           | next_start |                check_config                 | fixed_schedule | initial_start | timezone |   application_name    
--------+-------------------+-------------+-------------+-----------------+-----------+-----------------------------------------------------------+------------+---------------------------------------------+----------------+---------------+----------+-----------------------
   1014 | @ 3 years         | @ 5 mins    |           5 | @ 2 mins 3 secs | t         | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity  | _timescaledb_functions.policy_reorder_check | f              |               |          | Reorder Policy [1014]

select * from alter_job(:job_id, INTERVAL '123 years');
 job_id | schedule_interval | max_runtime | max_retries |  retry_period   | scheduled |                          config                           | next_start |                check_config                 | fixed_schedule | initial_start | timezone |   application_name    
--------+-------------------+-------------+-------------+-----------------+-----------+-----------------------------------------------------------+------------+---------------------------------------------+----------------+---------------+----------+-----------------------
   1014 | @ 123 years       | @ 5 mins    |           5 | @ 2 mins 3 secs | t         | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity  | _timescaledb_functions.policy_reorder_check | f              |               |          | Reorder Policy [1014]

select * from alter_job(:job_id, retry_period => INTERVAL '33 hours');
 job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled |                          config                           | next_start |                check_config                 | fixed_schedule | initial_start | timezone |   application_name    
--------+-------------------+-------------+-------------+--------------+-----------+-----------------------------------------------------------+------------+---------------------------------------------+----------------+---------------+----------+-----------------------
   1014 | @ 123 years       | @ 5 mins    |           5 | @ 33 hours   | t         | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity  | _timescaledb_functions.policy_reorder_check | f              |               |          | Reorder Policy [1014]

select * from alter_job(:job_id, max_runtime => INTERVAL '456 sec');
 job_id | schedule_interval |   max_runtime    | max_retries | retry_period | scheduled |                          config                           | next_start |                check_config                 | fixed_schedule | initial_start | timezone |   application_name    
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------+---------------------------------------------+----------------+---------------+----------+-----------------------
   1014 | @ 123 years       | @ 7 mins 36 secs |           5 | @ 33 hours   | t         | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity  | _timescaledb_functions.policy_reorder_check | f              |               |          | Reorder Policy [1014]

select * from alter_job(:job_id, max_retries => 0);
 job_id | schedule_interval |   max_runtime    | max_retries | retry_period | scheduled |                          config                           | next_start |                check_config                 | fixed_schedule | initial_start | timezone |   application_name    
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------+---------------------------------------------+----------------+---------------+----------+-----------------------
   1014 | @ 123 years       | @ 7 mins 36 secs |           0 | @ 33 hours   | t         | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity  | _timescaledb_functions.policy_reorder_check | f              |               |          | Reorder Policy [1014]

select * from alter_job(:job_id, max_retries => -1);
 job_id | schedule_interval |   max_runtime    | max_retries | retry_period | scheduled |                          config                           | next_start |                check_config                 | fixed_schedule | initial_start | timezone |   application_name    
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------+---------------------------------------------+----------------+---------------+----------+-----------------------
   1014 | @ 123 years       | @ 7 mins 36 secs |          -1 | @ 33 hours   | t         | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity  | _timescaledb_functions.policy_reorder_check | f              |               |          | Reorder Policy [1014]

select * from alter_job(:job_id, max_retries => 20);
 job_id | schedule_interval |   max_runtime    | max_retries | retry_period | scheduled |                          config                           | next_start |                check_config                 | fixed_schedule | initial_start | timezone |   application_name    
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------+---------------------------------------------+----------------+---------------+----------+-----------------------
   1014 | @ 123 years       | @ 7 mins 36 secs |          20 | @ 33 hours   | t         | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity  | _timescaledb_functions.policy_reorder_check | f              |               |          | Reorder Policy [1014]

-- No change
select * from alter_job(:job_id, max_runtime => NULL);
 job_id | schedule_interval |   max_runtime    | max_retries | retry_period | scheduled |                          config                           | next_start |                check_config                 | fixed_schedule | initial_start | timezone |   application_name    
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------+---------------------------------------------+----------------+---------------+----------+-----------------------
   1014 | @ 123 years       | @ 7 mins 36 secs |          20 | @ 33 hours   | t         | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity  | _timescaledb_functions.policy_reorder_check | f              |               |          | Reorder Policy [1014]

select * from alter_job(:job_id, max_retries => NULL);
 job_id | schedule_interval |   max_runtime    | max_retries | retry_period | scheduled |                          config                           | next_start |                check_config                 | fixed_schedule | initial_start | timezone |   application_name    
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------+---------------------------------------------+----------------+---------------+----------+-----------------------
   1014 | @ 123 years       | @ 7 mins 36 secs |          20 | @ 33 hours   | t         | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity  | _timescaledb_functions.policy_reorder_check | f              |               |          | Reorder Policy [1014]

--change schedule_interval when bgw_job_stat does not exist
select * from alter_job(:job_id, schedule_interval=>'1 min');
 job_id | schedule_interval |   max_runtime    | max_retries | retry_period | scheduled |                          config                           | next_start |                check_config                 | fixed_schedule | initial_start | timezone |   application_name    
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------+---------------------------------------------+----------------+---------------+----------+-----------------------
   1014 | @ 1 min           | @ 7 mins 36 secs |          20 | @ 33 hours   | t         | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity  | _timescaledb_functions.policy_reorder_check | f              |               |          | Reorder Policy [1014]

select count(*) = 0 from _timescaledb_internal.bgw_job_stat where job_id = :job_id;
 ?column? 
----------
 t

--set next_start when bgw_job_stat does not exist
select * from alter_job(:job_id, next_start=>'2001-01-01 01:01:01');
 job_id | schedule_interval |   max_runtime    | max_retries | retry_period | scheduled |                          config                           |          next_start          |                check_config                 | fixed_schedule | initial_start | timezone |   application_name    
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------------------------+---------------------------------------------+----------------+---------------+----------+-----------------------
   1014 | @ 1 min           | @ 7 mins 36 secs |          20 | @ 33 hours   | t         | {"index_name": "test_table_time_idx", "hypertable_id": 7} | Mon Jan 01 01:01:01 2001 PST | _timescaledb_functions.policy_reorder_check | f              |               |          | Reorder Policy [1014]

--change schedule_interval when no last_finish set
select * from alter_job(:job_id, schedule_interval=>'10 min');
 job_id | schedule_interval |   max_runtime    | max_retries | retry_period | scheduled |                          config                           | next_start |                check_config                 | fixed_schedule | initial_start | timezone |   application_name    
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------+---------------------------------------------+----------------+---------------+----------+-----------------------
   1014 | @ 10 mins         | @ 7 mins 36 secs |          20 | @ 33 hours   | t         | {"index_name": "test_table_time_idx", "hypertable_id": 7} | -infinity  | _timescaledb_functions.policy_reorder_check | f              |               |          | Reorder Policy [1014]

--next_start overrides any schedule_interval changes
select * from alter_job(:job_id, schedule_interval=>'20 min', next_start=>'2002-01-01 01:01:01');
 job_id | schedule_interval |   max_runtime    | max_retries | retry_period | scheduled |                          config                           |          next_start          |                check_config                 | fixed_schedule | initial_start | timezone |   application_name    
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------------------------+---------------------------------------------+----------------+---------------+----------+-----------------------
   1014 | @ 20 mins         | @ 7 mins 36 secs |          20 | @ 33 hours   | t         | {"index_name": "test_table_time_idx", "hypertable_id": 7} | Tue Jan 01 01:01:01 2002 PST | _timescaledb_functions.policy_reorder_check | f              |               |          | Reorder Policy [1014]

--set the last_finish manually
\c :TEST_DBNAME :ROLE_SUPERUSER
UPDATE _timescaledb_internal.bgw_job_stat SET last_finish = '2003-01-01:01:01:01' WHERE job_id = :job_id;
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
--not changing the interval doesn't change the next_start
select * from alter_job(:job_id, schedule_interval=>'20 min');
 job_id | schedule_interval |   max_runtime    | max_retries | retry_period | scheduled |                          config                           |          next_start          |                check_config                 | fixed_schedule | initial_start | timezone |   application_name    
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------------------------+---------------------------------------------+----------------+---------------+----------+-----------------------
   1014 | @ 20 mins         | @ 7 mins 36 secs |          20 | @ 33 hours   | t         | {"index_name": "test_table_time_idx", "hypertable_id": 7} | Tue Jan 01 01:01:01 2002 PST | _timescaledb_functions.policy_reorder_check | f              |               |          | Reorder Policy [1014]

--changing the interval changes next_start
select * from alter_job(:job_id, schedule_interval=>'30 min');
 job_id | schedule_interval |   max_runtime    | max_retries | retry_period | scheduled |                          config                           |          next_start          |                check_config                 | fixed_schedule | initial_start | timezone |   application_name    
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------------------------+---------------------------------------------+----------------+---------------+----------+-----------------------
   1014 | @ 30 mins         | @ 7 mins 36 secs |          20 | @ 33 hours   | t         | {"index_name": "test_table_time_idx", "hypertable_id": 7} | Wed Jan 01 01:31:01 2003 PST | _timescaledb_functions.policy_reorder_check | f              |               |          | Reorder Policy [1014]

--explicit next start overrides.
select * from alter_job(:job_id, schedule_interval=>'40 min', next_start=>'2004-01-01 01:01:01');
 job_id | schedule_interval |   max_runtime    | max_retries | retry_period | scheduled |                          config                           |          next_start          |                check_config                 | fixed_schedule | initial_start | timezone |   application_name    
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------------------------+---------------------------------------------+----------------+---------------+----------+-----------------------
   1014 | @ 40 mins         | @ 7 mins 36 secs |          20 | @ 33 hours   | t         | {"index_name": "test_table_time_idx", "hypertable_id": 7} | Thu Jan 01 01:01:01 2004 PST | _timescaledb_functions.policy_reorder_check | f              |               |          | Reorder Policy [1014]

--test pausing
select * from alter_job(:job_id, next_start=>'infinity');
 job_id | schedule_interval |   max_runtime    | max_retries | retry_period | scheduled |                          config                           | next_start |                check_config                 | fixed_schedule | initial_start | timezone |   application_name    
--------+-------------------+------------------+-------------+--------------+-----------+-----------------------------------------------------------+------------+---------------------------------------------+----------------+---------------+----------+-----------------------
   1014 | @ 40 mins         | @ 7 mins 36 secs |          20 | @ 33 hours   | t         | {"index_name": "test_table_time_idx", "hypertable_id": 7} | infinity   | _timescaledb_functions.policy_reorder_check | f              |               |          | Reorder Policy [1014]

--test that you can use now() to unpause
select next_start = now() from alter_job(:job_id, next_start=>now());
 ?column? 
----------
 t

--test pausing/resuming via scheduled parameter
select job_id from alter_job(:job_id, scheduled=>false);
 job_id 
--------
   1014

select job_status, next_start from timescaledb_information.job_stats where job_id = :job_id;
 job_status | next_start 
------------+------------
 Paused     | 

select job_id from alter_job(:job_id, scheduled=>true);
 job_id 
--------
   1014

select job_status from timescaledb_information.job_stats where job_id = :job_id;
 job_status 
------------
 Scheduled

\set ON_ERROR_STOP 0
-- negative infinity disallowed (used as special value)
select * from alter_job(:job_id, next_start=>'-infinity');
ERROR:  cannot set next start to -infinity
-- index should exist
select * from alter_job(:job_id,
       config => '{"index_name": "non-existent", "hypertable_id": 7}');
ERROR:  reorder index not found
-- index should be an index on the hypertable
select * from alter_job(:job_id,
       config => '{"index_name": "non_ht_index", "hypertable_id": 7}');
ERROR:  invalid reorder index
-- hypertable should exist
select * from alter_job(:job_id,
       config => '{"index_name": "test_table_time_idx", "hypertable_id": 47}');
ERROR:  configuration hypertable id 47 not found
\set ON_ERROR_STOP 1
-- Check if_exists boolean works correctly
select * from alter_job(1234, if_exists => TRUE);
NOTICE:  job 1234 not found, skipping
 job_id | schedule_interval | max_runtime | max_retries | retry_period | scheduled | config | next_start | check_config | fixed_schedule | initial_start | timezone | application_name 
--------+-------------------+-------------+-------------+--------------+-----------+--------+------------+--------------+----------------+---------------+----------+------------------
        |                   |             |             |              |           |        |            |              |                |               |          | 

\set ON_ERROR_STOP 0
select * from alter_job(1234);
ERROR:  job 1234 not found
\set ON_ERROR_STOP 1
select remove_reorder_policy('test_table');
 remove_reorder_policy 
-----------------------
 

\c :TEST_DBNAME :ROLE_SUPERUSER
set session timescaledb.license_key='Community';
-- Test for failure cases
\set ON_ERROR_STOP 0
select alter_job(12345);
ERROR:  job 12345 not found
\set ON_ERROR_STOP 1
select add_reorder_policy('test_table', 'test_table_time_idx') as reorder_job_id \gset
select add_retention_policy('test_table', INTERVAL '4 months', true) as drop_chunks_job_id \gset
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER_2
\set ON_ERROR_STOP 0
select from alter_job(:reorder_job_id, max_runtime => NULL);
ERROR:  insufficient permissions to alter job 1015
select from alter_job(:drop_chunks_job_id, max_runtime => NULL);
ERROR:  insufficient permissions to alter job 1016
\set ON_ERROR_STOP 1
