From a689e89f349d36738163068b16fc24bbe033931e Mon Sep 17 00:00:00 2001 From: James Guthrie Date: Tue, 26 Sep 2023 09:46:42 +0200 Subject: [PATCH] Add functions to enable/disable policies --- .unreleased/PR_6116 | 2 + sql/policy_api.sql | 91 +++++++- sql/updates/latest-dev.sql | 89 ++++++++ sql/updates/reverse-dev.sql | 11 + .../expected/policy_api_enable_disable.out | 194 ++++++++++++++++++ tsl/test/shared/expected/extension.out | 10 + tsl/test/sql/CMakeLists.txt | 1 + tsl/test/sql/policy_api_enable_disable.sql | 97 +++++++++ 8 files changed, 494 insertions(+), 1 deletion(-) create mode 100644 .unreleased/PR_6116 create mode 100644 tsl/test/expected/policy_api_enable_disable.out create mode 100644 tsl/test/sql/policy_api_enable_disable.sql diff --git a/.unreleased/PR_6116 b/.unreleased/PR_6116 new file mode 100644 index 00000000000..ae597c35558 --- /dev/null +++ b/.unreleased/PR_6116 @@ -0,0 +1,2 @@ +Implements: #6116 Add functions to enable/disable hypertable policies + diff --git a/sql/policy_api.sql b/sql/policy_api.sql index 0900ee361d1..7e762325e95 100644 --- a/sql/policy_api.sql +++ b/sql/policy_api.sql @@ -128,4 +128,93 @@ CREATE OR REPLACE FUNCTION timescaledb_experimental.show_policies( relation REGCLASS) RETURNS SETOF JSONB AS '@MODULE_PATHNAME@', 'ts_policies_show' -LANGUAGE C VOLATILE; \ No newline at end of file +LANGUAGE C VOLATILE; + +CREATE OR REPLACE FUNCTION _timescaledb_functions.set_policy_scheduled(hypertable REGCLASS, policy_type TEXT, scheduled BOOL) +RETURNS INTEGER +AS $$ + WITH affected_policies AS ( + SELECT @extschema@.alter_job(j.id, scheduled => set_policy_scheduled.scheduled) + FROM _timescaledb_config.bgw_job j + JOIN _timescaledb_catalog.hypertable h ON h.id = j.hypertable_id + WHERE j.proc_schema IN ('_timescaledb_internal', '_timescaledb_functions') + AND j.proc_name = set_policy_scheduled.policy_type + AND j.id >= 1000 + AND scheduled <> set_policy_scheduled.scheduled + AND format('%I.%I', h.schema_name, h.table_name)::text::regclass = set_policy_scheduled.hypertable + ) +SELECT count(*) FROM affected_policies; +$$ +LANGUAGE SQL SET search_path TO pg_catalog, pg_temp; + +CREATE OR REPLACE FUNCTION _timescaledb_functions.set_all_policy_scheduled(hypertable REGCLASS, scheduled BOOL) +RETURNS INTEGER +AS $$ + WITH affected_policies AS ( + SELECT @extschema@.alter_job(j.id, scheduled => set_all_policy_scheduled.scheduled) + FROM _timescaledb_config.bgw_job j + JOIN _timescaledb_catalog.hypertable h ON h.id = j.hypertable_id + WHERE j.proc_schema IN ('_timescaledb_internal', '_timescaledb_functions') + AND j.id >= 1000 + AND scheduled <> set_all_policy_scheduled.scheduled + AND format('%I.%I', h.schema_name, h.table_name)::text::regclass = set_all_policy_scheduled.hypertable + ) +SELECT count(*) FROM affected_policies; +$$ +LANGUAGE SQL SET search_path TO pg_catalog, pg_temp; + +CREATE OR REPLACE FUNCTION @extschema@.disable_all_policies(hypertable REGCLASS) +RETURNS INTEGER +AS $$ +SELECT _timescaledb_functions.set_all_policy_scheduled(hypertable, false); +$$ +LANGUAGE SQL SET search_path TO pg_catalog, pg_temp; + +CREATE OR REPLACE FUNCTION @extschema@.enable_all_policies(hypertable REGCLASS) +RETURNS INTEGER +AS $$ +SELECT _timescaledb_functions.set_all_policy_scheduled(hypertable, true); +$$ +LANGUAGE SQL SET search_path TO pg_catalog, pg_temp; + +CREATE OR REPLACE FUNCTION @extschema@.disable_compression_policy(hypertable REGCLASS) +RETURNS INTEGER +AS $$ +SELECT _timescaledb_functions.set_policy_scheduled(hypertable, 'policy_compression', false); +$$ +LANGUAGE SQL SET search_path TO pg_catalog, pg_temp; + +CREATE OR REPLACE FUNCTION @extschema@.enable_compression_policy(hypertable REGCLASS) +RETURNS INTEGER +AS $$ +SELECT _timescaledb_functions.set_policy_scheduled(hypertable, 'policy_compression', true); +$$ +LANGUAGE SQL SET search_path TO pg_catalog, pg_temp; + +CREATE OR REPLACE FUNCTION @extschema@.disable_reorder_policy(hypertable REGCLASS) +RETURNS INTEGER +AS $$ +SELECT _timescaledb_functions.set_policy_scheduled(hypertable, 'policy_reorder', false); +$$ +LANGUAGE SQL SET search_path TO pg_catalog, pg_temp; + +CREATE OR REPLACE FUNCTION @extschema@.enable_reorder_policy(hypertable REGCLASS) +RETURNS INTEGER +AS $$ +SELECT _timescaledb_functions.set_policy_scheduled(hypertable, 'policy_reorder', true); +$$ +LANGUAGE SQL SET search_path TO pg_catalog, pg_temp; + +CREATE OR REPLACE FUNCTION @extschema@.disable_retention_policy(hypertable REGCLASS) +RETURNS INTEGER +AS $$ +SELECT _timescaledb_functions.set_policy_scheduled(hypertable, 'policy_retention', false); +$$ +LANGUAGE SQL SET search_path TO pg_catalog, pg_temp; + +CREATE OR REPLACE FUNCTION @extschema@.enable_retention_policy(hypertable REGCLASS) +RETURNS INTEGER +AS $$ +SELECT _timescaledb_functions.set_policy_scheduled(hypertable, 'policy_retention', true); +$$ +LANGUAGE SQL SET search_path TO pg_catalog, pg_temp; diff --git a/sql/updates/latest-dev.sql b/sql/updates/latest-dev.sql index e69de29bb2d..95fdebd9e2a 100644 --- a/sql/updates/latest-dev.sql +++ b/sql/updates/latest-dev.sql @@ -0,0 +1,89 @@ +CREATE FUNCTION _timescaledb_functions.set_policy_scheduled(hypertable REGCLASS, policy_type TEXT, scheduled BOOL) +RETURNS INTEGER +AS $$ + WITH affected_policies AS ( + SELECT @extschema@.alter_job(j.id, scheduled => set_policy_scheduled.scheduled) + FROM _timescaledb_config.bgw_job j + JOIN _timescaledb_catalog.hypertable h ON h.id = j.hypertable_id + WHERE j.proc_schema IN ('_timescaledb_internal', '_timescaledb_functions') + AND j.proc_name = set_policy_scheduled.policy_type + AND j.id >= 1000 + AND scheduled <> set_policy_scheduled.scheduled + AND format('%I.%I', h.schema_name, h.table_name)::text::regclass = set_policy_scheduled.hypertable + ) +SELECT count(*) FROM affected_policies; +$$ +LANGUAGE SQL SET search_path TO pg_catalog, pg_temp; + +CREATE FUNCTION _timescaledb_functions.set_all_policy_scheduled(hypertable REGCLASS, scheduled BOOL) +RETURNS INTEGER +AS $$ + WITH affected_policies AS ( + SELECT @extschema@.alter_job(j.id, scheduled => set_all_policy_scheduled.scheduled) + FROM _timescaledb_config.bgw_job j + JOIN _timescaledb_catalog.hypertable h ON h.id = j.hypertable_id + WHERE j.proc_schema IN ('_timescaledb_internal', '_timescaledb_functions') + AND j.id >= 1000 + AND scheduled <> set_all_policy_scheduled.scheduled + AND format('%I.%I', h.schema_name, h.table_name)::text::regclass = set_all_policy_scheduled.hypertable + ) +SELECT count(*) FROM affected_policies; +$$ +LANGUAGE SQL SET search_path TO pg_catalog, pg_temp; + +CREATE FUNCTION @extschema@.disable_all_policies(hypertable REGCLASS) +RETURNS INTEGER +AS $$ +SELECT _timescaledb_functions.set_all_policy_scheduled(hypertable, false); +$$ +LANGUAGE SQL SET search_path TO pg_catalog, pg_temp; + +CREATE FUNCTION @extschema@.enable_all_policies(hypertable REGCLASS) +RETURNS INTEGER +AS $$ +SELECT _timescaledb_functions.set_all_policy_scheduled(hypertable, true); +$$ +LANGUAGE SQL SET search_path TO pg_catalog, pg_temp; + +CREATE FUNCTION @extschema@.disable_compression_policy(hypertable REGCLASS) +RETURNS INTEGER +AS $$ +SELECT _timescaledb_functions.set_policy_scheduled(hypertable, 'policy_compression', false); +$$ +LANGUAGE SQL SET search_path TO pg_catalog, pg_temp; + +CREATE FUNCTION @extschema@.enable_compression_policy(hypertable REGCLASS) +RETURNS INTEGER +AS $$ +SELECT _timescaledb_functions.set_policy_scheduled(hypertable, 'policy_compression', true); +$$ +LANGUAGE SQL SET search_path TO pg_catalog, pg_temp; + +CREATE FUNCTION @extschema@.disable_reorder_policy(hypertable REGCLASS) +RETURNS INTEGER +AS $$ +SELECT _timescaledb_functions.set_policy_scheduled(hypertable, 'policy_reorder', false); +$$ +LANGUAGE SQL SET search_path TO pg_catalog, pg_temp; + +CREATE FUNCTION @extschema@.enable_reorder_policy(hypertable REGCLASS) +RETURNS INTEGER +AS $$ +SELECT _timescaledb_functions.set_policy_scheduled(hypertable, 'policy_reorder', true); +$$ +LANGUAGE SQL SET search_path TO pg_catalog, pg_temp; + +CREATE FUNCTION @extschema@.disable_retention_policy(hypertable REGCLASS) +RETURNS INTEGER +AS $$ +SELECT _timescaledb_functions.set_policy_scheduled(hypertable, 'policy_retention', false); +$$ +LANGUAGE SQL SET search_path TO pg_catalog, pg_temp; + +CREATE FUNCTION @extschema@.enable_retention_policy(hypertable REGCLASS) +RETURNS INTEGER +AS $$ +SELECT _timescaledb_functions.set_policy_scheduled(hypertable, 'policy_retention', true); +$$ +LANGUAGE SQL SET search_path TO pg_catalog, pg_temp; + diff --git a/sql/updates/reverse-dev.sql b/sql/updates/reverse-dev.sql index e69de29bb2d..9631de96518 100644 --- a/sql/updates/reverse-dev.sql +++ b/sql/updates/reverse-dev.sql @@ -0,0 +1,11 @@ + +DROP FUNCTION _timescaledb_functions.set_policy_scheduled(hypertable REGCLASS, policy_type TEXT, scheduled BOOL); +DROP FUNCTION _timescaledb_functions.set_all_policy_scheduled(hypertable REGCLASS, scheduled BOOL); +DROP FUNCTION @extschema@.disable_all_policies(hypertable REGCLASS); +DROP FUNCTION @extschema@.enable_all_policies(hypertable REGCLASS); +DROP FUNCTION @extschema@.disable_compression_policy(hypertable REGCLASS); +DROP FUNCTION @extschema@.enable_compression_policy(hypertable REGCLASS); +DROP FUNCTION @extschema@.disable_reorder_policy(hypertable REGCLASS); +DROP FUNCTION @extschema@.enable_reorder_policy(hypertable REGCLASS); +DROP FUNCTION @extschema@.disable_retention_policy(hypertable REGCLASS); +DROP FUNCTION @extschema@.enable_retention_policy(hypertable REGCLASS); \ No newline at end of file diff --git a/tsl/test/expected/policy_api_enable_disable.out b/tsl/test/expected/policy_api_enable_disable.out new file mode 100644 index 00000000000..c52698b331b --- /dev/null +++ b/tsl/test/expected/policy_api_enable_disable.out @@ -0,0 +1,194 @@ +-- 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. +CREATE TABLE test_table(time timestamptz, chunk_id int); +SELECT create_hypertable('test_table', 'time'); +NOTICE: adding not-null constraint to column "time" + create_hypertable +------------------------- + (1,public,test_table,t) +(1 row) + +ALTER TABLE test_table SET (timescaledb.compress); +-- reorder +SELECT add_reorder_policy('test_table', 'test_table_time_idx') AS reorder_job_id \gset +SELECT disable_reorder_policy('test_table') AS affected_policies \gset +SELECT :affected_policies=1; + ?column? +---------- + t +(1 row) + +SELECT disable_reorder_policy('test_table') AS affected_policies \gset +SELECT :affected_policies=0; + ?column? +---------- + t +(1 row) + +SELECT scheduled FROM _timescaledb_config.bgw_job WHERE id = :reorder_job_id \gset +SELECT :'scheduled'::bool = false; + ?column? +---------- + t +(1 row) + +SELECT enable_reorder_policy('test_table') AS affected_policies \gset +SELECT :affected_policies=1; + ?column? +---------- + t +(1 row) + +SELECT enable_reorder_policy('test_table') AS affected_policies \gset +SELECT :affected_policies=0; + ?column? +---------- + t +(1 row) + +SELECT scheduled FROM _timescaledb_config.bgw_job WHERE id = :reorder_job_id \gset +SELECT :'scheduled'::bool = true; + ?column? +---------- + t +(1 row) + +SELECT remove_reorder_policy('test_table'); + remove_reorder_policy +----------------------- + +(1 row) + +-- retention +SELECT add_retention_policy('test_table', INTERVAL '4 months', true) AS retention_job_id \gset +SELECT disable_retention_policy('test_table') AS affected_policies \gset +SELECT :affected_policies=1; + ?column? +---------- + t +(1 row) + +SELECT disable_retention_policy('test_table') AS affected_policies \gset +SELECT :affected_policies=0; + ?column? +---------- + t +(1 row) + +SELECT scheduled FROM _timescaledb_config.bgw_job WHERE id = :retention_job_id \gset +SELECT :'scheduled'::bool = false; + ?column? +---------- + t +(1 row) + +SELECT enable_retention_policy('test_table') AS affected_policies \gset +SELECT :affected_policies=1; + ?column? +---------- + t +(1 row) + +SELECT enable_retention_policy('test_table') AS affected_policies \gset +SELECT :affected_policies=0; + ?column? +---------- + t +(1 row) + +SELECT scheduled FROM _timescaledb_config.bgw_job WHERE id = :retention_job_id \gset +SELECT :'scheduled'::bool = true; + ?column? +---------- + t +(1 row) + +SELECT remove_retention_policy('test_table'); + remove_retention_policy +------------------------- + +(1 row) + +-- compression +SELECT add_compression_policy('test_table', compress_after => '1 month'::INTERVAL) AS compression_job_id \gset +SELECT disable_compression_policy('test_table') AS affected_policies \gset +SELECT :affected_policies=1; + ?column? +---------- + t +(1 row) + +SELECT disable_compression_policy('test_table') AS affected_policies \gset +SELECT :affected_policies=0; + ?column? +---------- + t +(1 row) + +SELECT scheduled FROM _timescaledb_config.bgw_job WHERE id = :compression_job_id \gset +SELECT :'scheduled'::bool = false; + ?column? +---------- + t +(1 row) + +SELECT enable_compression_policy('test_table') AS affected_policies \gset +SELECT :affected_policies=1; + ?column? +---------- + t +(1 row) + +SELECT enable_compression_policy('test_table') AS affected_policies \gset +SELECT :affected_policies=0; + ?column? +---------- + t +(1 row) + +SELECT scheduled FROM _timescaledb_config.bgw_job WHERE id = :compression_job_id \gset +SELECT :'scheduled'::bool = true; + ?column? +---------- + t +(1 row) + +SELECT remove_compression_policy('test_table'); + remove_compression_policy +--------------------------- + t +(1 row) + +-- all together now +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 retention_job_id \gset +SELECT add_compression_policy('test_table', compress_after => '1 month'::INTERVAL) AS compression_job_id \gset +SELECT disable_all_policies('test_table') AS affected_policies \gset +SELECT :affected_policies = 3; + ?column? +---------- + t +(1 row) + +SELECT disable_all_policies('test_table') AS affected_policies \gset +SELECT :affected_policies = 0; + ?column? +---------- + t +(1 row) + +SELECT enable_all_policies('test_table') AS affected_policies \gset +SELECT :affected_policies = 3; + ?column? +---------- + t +(1 row) + +SELECT enable_all_policies('test_table') AS affected_policies \gset +SELECT :affected_policies = 0; + ?column? +---------- + t +(1 row) + diff --git a/tsl/test/shared/expected/extension.out b/tsl/test/shared/expected/extension.out index 23d851e5f5d..f4730078aee 100644 --- a/tsl/test/shared/expected/extension.out +++ b/tsl/test/shared/expected/extension.out @@ -128,9 +128,11 @@ ORDER BY pronamespace::regnamespace::text COLLATE "C", p.oid::regprocedure::text _timescaledb_functions.restart_background_workers() _timescaledb_functions.rxid_in(cstring) _timescaledb_functions.rxid_out(rxid) + _timescaledb_functions.set_all_policy_scheduled(regclass,boolean) _timescaledb_functions.set_chunk_default_data_node(regclass,name) _timescaledb_functions.set_dist_id(uuid) _timescaledb_functions.set_peer_dist_id(uuid) + _timescaledb_functions.set_policy_scheduled(regclass,text,boolean) _timescaledb_functions.show_chunk(regclass) _timescaledb_functions.show_connection_cache() _timescaledb_functions.start_background_workers() @@ -282,8 +284,16 @@ ORDER BY pronamespace::regnamespace::text COLLATE "C", p.oid::regprocedure::text detach_data_node(name,regclass,boolean,boolean,boolean,boolean) detach_tablespace(name,regclass,boolean) detach_tablespaces(regclass) + disable_all_policies(regclass) + disable_compression_policy(regclass) + disable_reorder_policy(regclass) + disable_retention_policy(regclass) distributed_exec(text,name[],boolean) drop_chunks(regclass,"any","any",boolean) + enable_all_policies(regclass) + enable_compression_policy(regclass) + enable_reorder_policy(regclass) + enable_retention_policy(regclass) first(anyelement,"any") histogram(double precision,double precision,double precision,integer) hypertable_compression_stats(regclass) diff --git a/tsl/test/sql/CMakeLists.txt b/tsl/test/sql/CMakeLists.txt index b6e8f6aa354..80b930982cb 100644 --- a/tsl/test/sql/CMakeLists.txt +++ b/tsl/test/sql/CMakeLists.txt @@ -26,6 +26,7 @@ set(TEST_FILES exp_cagg_timezone.sql move.sql partialize_finalize.sql + policy_api_enable_disable.sql reorder.sql skip_scan.sql size_utils_tsl.sql) diff --git a/tsl/test/sql/policy_api_enable_disable.sql b/tsl/test/sql/policy_api_enable_disable.sql new file mode 100644 index 00000000000..681fcecd432 --- /dev/null +++ b/tsl/test/sql/policy_api_enable_disable.sql @@ -0,0 +1,97 @@ +-- 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. + +CREATE TABLE test_table(time timestamptz, chunk_id int); +SELECT create_hypertable('test_table', 'time'); +ALTER TABLE test_table SET (timescaledb.compress); + +-- reorder + +SELECT add_reorder_policy('test_table', 'test_table_time_idx') AS reorder_job_id \gset + +SELECT disable_reorder_policy('test_table') AS affected_policies \gset +SELECT :affected_policies=1; + +SELECT disable_reorder_policy('test_table') AS affected_policies \gset +SELECT :affected_policies=0; + +SELECT scheduled FROM _timescaledb_config.bgw_job WHERE id = :reorder_job_id \gset +SELECT :'scheduled'::bool = false; + +SELECT enable_reorder_policy('test_table') AS affected_policies \gset +SELECT :affected_policies=1; + +SELECT enable_reorder_policy('test_table') AS affected_policies \gset +SELECT :affected_policies=0; + +SELECT scheduled FROM _timescaledb_config.bgw_job WHERE id = :reorder_job_id \gset +SELECT :'scheduled'::bool = true; + +SELECT remove_reorder_policy('test_table'); + +-- retention + +SELECT add_retention_policy('test_table', INTERVAL '4 months', true) AS retention_job_id \gset + +SELECT disable_retention_policy('test_table') AS affected_policies \gset +SELECT :affected_policies=1; + +SELECT disable_retention_policy('test_table') AS affected_policies \gset +SELECT :affected_policies=0; + +SELECT scheduled FROM _timescaledb_config.bgw_job WHERE id = :retention_job_id \gset +SELECT :'scheduled'::bool = false; + +SELECT enable_retention_policy('test_table') AS affected_policies \gset +SELECT :affected_policies=1; + +SELECT enable_retention_policy('test_table') AS affected_policies \gset +SELECT :affected_policies=0; + +SELECT scheduled FROM _timescaledb_config.bgw_job WHERE id = :retention_job_id \gset +SELECT :'scheduled'::bool = true; + +SELECT remove_retention_policy('test_table'); + +-- compression + +SELECT add_compression_policy('test_table', compress_after => '1 month'::INTERVAL) AS compression_job_id \gset + +SELECT disable_compression_policy('test_table') AS affected_policies \gset +SELECT :affected_policies=1; + +SELECT disable_compression_policy('test_table') AS affected_policies \gset +SELECT :affected_policies=0; + +SELECT scheduled FROM _timescaledb_config.bgw_job WHERE id = :compression_job_id \gset +SELECT :'scheduled'::bool = false; + +SELECT enable_compression_policy('test_table') AS affected_policies \gset +SELECT :affected_policies=1; + +SELECT enable_compression_policy('test_table') AS affected_policies \gset +SELECT :affected_policies=0; + +SELECT scheduled FROM _timescaledb_config.bgw_job WHERE id = :compression_job_id \gset +SELECT :'scheduled'::bool = true; + +SELECT remove_compression_policy('test_table'); + +-- all together now + +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 retention_job_id \gset +SELECT add_compression_policy('test_table', compress_after => '1 month'::INTERVAL) AS compression_job_id \gset + +SELECT disable_all_policies('test_table') AS affected_policies \gset +SELECT :affected_policies = 3; + +SELECT disable_all_policies('test_table') AS affected_policies \gset +SELECT :affected_policies = 0; + +SELECT enable_all_policies('test_table') AS affected_policies \gset +SELECT :affected_policies = 3; + +SELECT enable_all_policies('test_table') AS affected_policies \gset +SELECT :affected_policies = 0;