mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-15 10:11:29 +08:00
This simplifies the process of adding the policies for the CAggs. Now, with one single sql statements all the policies can be added for a given CAgg. Similarly, all the policies can be removed or modified via single sql statement only. This also adds a new function as well as a view to show all the policies on a continuous aggregate.
509 lines
21 KiB
PL/PgSQL
509 lines
21 KiB
PL/PgSQL
-- 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.
|
|
|
|
-- test add and remove refresh policy apis
|
|
|
|
SET ROLE :ROLE_DEFAULT_PERM_USER;
|
|
|
|
|
|
--TEST1 ---
|
|
--basic test with count
|
|
CREATE TABLE int_tab (a integer, b integer, c integer);
|
|
SELECT table_name FROM create_hypertable('int_tab', 'a', chunk_time_interval=> 10);
|
|
|
|
INSERT INTO int_tab VALUES( 3 , 16 , 20);
|
|
INSERT INTO int_tab VALUES( 1 , 10 , 20);
|
|
INSERT INTO int_tab VALUES( 1 , 11 , 20);
|
|
INSERT INTO int_tab VALUES( 1 , 12 , 20);
|
|
INSERT INTO int_tab VALUES( 1 , 13 , 20);
|
|
INSERT INTO int_tab VALUES( 1 , 14 , 20);
|
|
INSERT INTO int_tab VALUES( 2 , 14 , 20);
|
|
INSERT INTO int_tab VALUES( 2 , 15 , 20);
|
|
INSERT INTO int_tab VALUES( 2 , 16 , 20);
|
|
|
|
CREATE OR REPLACE FUNCTION integer_now_int_tab() returns int LANGUAGE SQL STABLE as $$ SELECT coalesce(max(a), 0) FROM int_tab $$;
|
|
SELECT set_integer_now_func('int_tab', 'integer_now_int_tab');
|
|
|
|
|
|
CREATE MATERIALIZED VIEW mat_m1( a, countb )
|
|
WITH (timescaledb.continuous, timescaledb.materialized_only=true)
|
|
as
|
|
SELECT a, count(b)
|
|
FROM int_tab
|
|
GROUP BY time_bucket(1, a), a WITH NO DATA;
|
|
|
|
\c :TEST_DBNAME :ROLE_SUPERUSER
|
|
DELETE FROM _timescaledb_config.bgw_job WHERE TRUE;
|
|
|
|
SET ROLE :ROLE_DEFAULT_PERM_USER;
|
|
SELECT count(*) FROM _timescaledb_config.bgw_job;
|
|
|
|
\set ON_ERROR_STOP 0
|
|
\set VERBOSITY default
|
|
|
|
-- Test 1 step policy for integer type buckets
|
|
ALTER materialized view mat_m1 set (timescaledb.compress = true);
|
|
-- No policy is added if one errors out
|
|
SELECT add_policies('mat_m1', refresh_start_offset => 1, refresh_end_offset => 10, refresh_schedule_interval =>'1 h'::interval, compress_after => 11, drop_after => 20);
|
|
SELECT show_policies('mat_m1');
|
|
|
|
-- All policies are added in one step
|
|
SELECT add_policies('mat_m1', refresh_start_offset => 10, refresh_end_offset => 1, refresh_schedule_interval =>'1 h'::interval, compress_after => 11, drop_after => 20);
|
|
SELECT show_policies('mat_m1');
|
|
|
|
-- Alter policies
|
|
SELECT alter_policies('mat_m1', refresh_schedule_interval =>'2 h'::interval, compress_after=>11, drop_after => 15);
|
|
SELECT show_policies('mat_m1');
|
|
|
|
-- Remove one or more policy
|
|
SELECT remove_policies('mat_m1', false, 'policy_refresh_continuous_aggregate', 'policy_compression');
|
|
SELECT show_policies('mat_m1');
|
|
|
|
-- Add one policy
|
|
SELECT add_policies('mat_m1', refresh_start_offset => 10, refresh_end_offset => 1, refresh_schedule_interval =>'1 h'::interval);
|
|
SELECT show_policies('mat_m1');
|
|
|
|
-- Remove all policies
|
|
SELECT remove_policies('mat_m1', false, 'policy_refresh_continuous_aggregate', 'policy_retention');
|
|
SELECT show_policies('mat_m1');
|
|
|
|
ALTER materialized view mat_m1 set (timescaledb.compress = false);
|
|
|
|
SELECT add_continuous_aggregate_policy('int_tab', '1 day'::interval, 10 , '1 h'::interval);
|
|
SELECT add_continuous_aggregate_policy('mat_m1', '1 day'::interval, 10 , '1 h'::interval);
|
|
SELECT add_continuous_aggregate_policy('mat_m1', '1 day'::interval, 10 );
|
|
SELECT add_continuous_aggregate_policy('mat_m1', 10, '1 day'::interval, '1 h'::interval);
|
|
--start_interval < end_interval
|
|
SELECT add_continuous_aggregate_policy('mat_m1', 5, 10, '1h'::interval);
|
|
--refresh window less than two buckets
|
|
SELECT add_continuous_aggregate_policy('mat_m1', 11, 10, '1h'::interval);
|
|
SELECT add_continuous_aggregate_policy('mat_m1', 20, 10, '1h'::interval) as job_id \gset
|
|
|
|
--adding again should warn/error
|
|
SELECT add_continuous_aggregate_policy('mat_m1', 20, 10, '1h'::interval, if_not_exists=>false);
|
|
SELECT add_continuous_aggregate_policy('mat_m1', 20, 15, '1h'::interval, if_not_exists=>true);
|
|
SELECT add_continuous_aggregate_policy('mat_m1', 20, 10, '1h'::interval, if_not_exists=>true);
|
|
|
|
-- modify config and try to add, should error out
|
|
SELECT config FROM _timescaledb_config.bgw_job where id = :job_id;
|
|
SELECT hypertable_id as mat_id FROM _timescaledb_config.bgw_job where id = :job_id \gset
|
|
\set VERBOSITY terse
|
|
\set ON_ERROR_STOP 1
|
|
|
|
\c :TEST_DBNAME :ROLE_SUPERUSER
|
|
UPDATE _timescaledb_config.bgw_job
|
|
SET config = jsonb_build_object('mat_hypertable_id', :mat_id)
|
|
WHERE id = :job_id;
|
|
SET ROLE :ROLE_DEFAULT_PERM_USER;
|
|
SELECT config FROM _timescaledb_config.bgw_job where id = :job_id;
|
|
|
|
\set ON_ERROR_STOP 0
|
|
\set VERBOSITY default
|
|
SELECT add_continuous_aggregate_policy('mat_m1', 20, 10, '1h'::interval, if_not_exists=>true);
|
|
|
|
SELECT remove_continuous_aggregate_policy('int_tab');
|
|
SELECT remove_continuous_aggregate_policy('mat_m1');
|
|
--this one will fail
|
|
SELECT remove_continuous_aggregate_policy('mat_m1');
|
|
SELECT remove_continuous_aggregate_policy('mat_m1', if_not_exists=>true);
|
|
|
|
--now try to add a policy as a different user than the one that created the cagg
|
|
--should fail
|
|
SET ROLE :ROLE_DEFAULT_PERM_USER_2;
|
|
SELECT add_continuous_aggregate_policy('mat_m1', 20, 10, '1h'::interval) as job_id ;
|
|
\set VERBOSITY terse
|
|
\set ON_ERROR_STOP 1
|
|
|
|
SET ROLE :ROLE_DEFAULT_PERM_USER;
|
|
DROP MATERIALIZED VIEW mat_m1;
|
|
|
|
--- code coverage tests : add policy for timestamp and date based table ---
|
|
CREATE TABLE continuous_agg_max_mat_date(time DATE);
|
|
SELECT create_hypertable('continuous_agg_max_mat_date', 'time');
|
|
CREATE MATERIALIZED VIEW max_mat_view_date
|
|
WITH (timescaledb.continuous, timescaledb.materialized_only=true)
|
|
AS SELECT time_bucket('7 days', time)
|
|
FROM continuous_agg_max_mat_date
|
|
GROUP BY 1 WITH NO DATA;
|
|
|
|
\set ON_ERROR_STOP 0
|
|
\set VERBOSITY default
|
|
|
|
-- Test 1 step policy for timestamp type buckets
|
|
ALTER materialized view max_mat_view_date set (timescaledb.compress = true);
|
|
-- Only works for cagg
|
|
SELECT add_policies('continuous_agg_max_mat_date', refresh_start_offset => '1 day'::interval, refresh_end_offset => '2 day'::interval, refresh_schedule_interval =>'1 h'::interval, compress_after => '20 days'::interval, drop_after => '25 days'::interval);
|
|
SELECT show_policies('continuous_agg_max_mat_date');
|
|
SELECT alter_policies('continuous_agg_max_mat_date', compress_after=>'16 days'::interval);
|
|
SELECT remove_policies('continuous_agg_max_mat_date', false, 'policy_refresh_continuous_aggregate');
|
|
|
|
-- No policy is added if one errors out
|
|
SELECT add_policies('max_mat_view_date', refresh_start_offset => '1 day'::interval, refresh_end_offset => '2 day'::interval, refresh_schedule_interval =>'1 h'::interval, compress_after => '20 days'::interval, drop_after => '25 days'::interval);
|
|
SELECT show_policies('max_mat_view_date');
|
|
|
|
-- Refresh schedule interval cannot be NULL
|
|
SELECT add_policies('max_mat_view_date', refresh_start_offset => '1 day'::interval, refresh_end_offset => '2 day'::interval, compress_after => '20 days'::interval, drop_after => '25 days'::interval);
|
|
|
|
-- All policies are added in one step
|
|
SELECT add_policies('max_mat_view_date', refresh_start_offset => '15 days'::interval, refresh_end_offset => '1 day'::interval, refresh_schedule_interval =>'1 h'::interval, compress_after => '20 days'::interval, drop_after => '25 days'::interval);
|
|
SELECT show_policies('max_mat_view_date');
|
|
|
|
-- Alter policies
|
|
SELECT alter_policies('max_mat_view_date', refresh_schedule_interval =>'2 h', compress_after=>'16 days'::interval, drop_after => '20 days'::interval);
|
|
SELECT show_policies('max_mat_view_date');
|
|
|
|
-- Remove one or more policy
|
|
-- Code coverage: no policy names provided
|
|
SELECT remove_policies('max_mat_view_date', false);
|
|
|
|
-- Code coverage: incorrect name of policy
|
|
SELECT remove_policies('max_mat_view_date', false, 'refresh_policy');
|
|
|
|
SELECT remove_policies('max_mat_view_date', false, 'policy_refresh_continuous_aggregate', 'policy_compression');
|
|
SELECT show_policies('max_mat_view_date');
|
|
|
|
-- Add one policy
|
|
SELECT add_policies('max_mat_view_date', refresh_start_offset => '15 day'::interval, refresh_end_offset => '1 day'::interval, refresh_schedule_interval =>'1 h'::interval);
|
|
SELECT show_policies('max_mat_view_date');
|
|
|
|
-- Remove all policies
|
|
SELECT remove_policies('max_mat_view_date', false, 'policy_refresh_continuous_aggregate', 'policy_retention');
|
|
SELECT show_policies('max_mat_view_date');
|
|
|
|
ALTER materialized view max_mat_view_date set (timescaledb.compress = false);
|
|
|
|
SELECT add_continuous_aggregate_policy('max_mat_view_date', '2 days', 10, '1 day'::interval);
|
|
--start_interval < end_interval
|
|
SELECT add_continuous_aggregate_policy('max_mat_view_date', '1 day'::interval, '2 days'::interval , '1 day'::interval) ;
|
|
--interval less than two buckets
|
|
SELECT add_continuous_aggregate_policy('max_mat_view_date', '7 days', '1 day', '1 day'::interval);
|
|
SELECT add_continuous_aggregate_policy('max_mat_view_date', '14 days', '1 day', '1 day'::interval);
|
|
SELECT add_continuous_aggregate_policy('max_mat_view_date', '13 days', '-10 hours', '1 day'::interval);
|
|
\set VERBOSITY terse
|
|
\set ON_ERROR_STOP 1
|
|
|
|
-- Negative start offset gives two bucket window:
|
|
SELECT add_continuous_aggregate_policy('max_mat_view_date', '13 days', '-1 day', '1 day'::interval);
|
|
SELECT remove_continuous_aggregate_policy('max_mat_view_date');
|
|
-- Both offsets NULL:
|
|
SELECT add_continuous_aggregate_policy('max_mat_view_date', NULL, NULL, '1 day'::interval);
|
|
SELECT remove_continuous_aggregate_policy('max_mat_view_date');
|
|
|
|
SELECT add_continuous_aggregate_policy('max_mat_view_date', '15 days', '1 day', '1 day'::interval) as job_id \gset
|
|
SELECT config FROM _timescaledb_config.bgw_job
|
|
WHERE id = :job_id;
|
|
|
|
INSERT INTO continuous_agg_max_mat_date
|
|
SELECT generate_series('2019-09-01'::date, '2019-09-10'::date, '1 day');
|
|
--- to prevent NOTICES set message level to warning
|
|
SET client_min_messages TO warning;
|
|
CALL run_job(:job_id);
|
|
RESET client_min_messages;
|
|
DROP MATERIALIZED VIEW max_mat_view_date;
|
|
|
|
CREATE TABLE continuous_agg_timestamp(time TIMESTAMP);
|
|
SELECT create_hypertable('continuous_agg_timestamp', 'time');
|
|
|
|
CREATE MATERIALIZED VIEW max_mat_view_timestamp
|
|
WITH (timescaledb.continuous, timescaledb.materialized_only=true)
|
|
AS SELECT time_bucket('7 days', time)
|
|
FROM continuous_agg_timestamp
|
|
GROUP BY 1 WITH NO DATA;
|
|
|
|
--the start offset overflows the smallest time value, but is capped at
|
|
--the min value
|
|
SELECT add_continuous_aggregate_policy('max_mat_view_timestamp', '1000000 years', '1 day' , '1 h'::interval);
|
|
SELECT remove_continuous_aggregate_policy('max_mat_view_timestamp');
|
|
|
|
\set ON_ERROR_STOP 0
|
|
\set VERBOSITY default
|
|
--start and end offset capped at the lowest time value, which means
|
|
--zero size window
|
|
SELECT add_continuous_aggregate_policy('max_mat_view_timestamp', '1000000 years', '900000 years' , '1 h'::interval);
|
|
SELECT add_continuous_aggregate_policy('max_mat_view_timestamp', '301 days', '10 months' , '1 h'::interval);
|
|
\set VERBOSITY terse
|
|
\set ON_ERROR_STOP 1
|
|
|
|
SELECT add_continuous_aggregate_policy('max_mat_view_timestamp', '15 days', '1 h'::interval , '1 h'::interval) as job_id \gset
|
|
|
|
--- to prevent NOTICES set message level to warning
|
|
SET client_min_messages TO warning;
|
|
CALL run_job(:job_id);
|
|
RESET client_min_messages ;
|
|
|
|
SELECT config FROM _timescaledb_config.bgw_job
|
|
WHERE id = :job_id;
|
|
|
|
\c :TEST_DBNAME :ROLE_SUPERUSER
|
|
UPDATE _timescaledb_config.bgw_job
|
|
SET config = jsonb_build_object('mat_hypertable_id', :mat_id)
|
|
WHERE id = :job_id;
|
|
|
|
SET ROLE :ROLE_DEFAULT_PERM_USER;
|
|
SELECT config FROM _timescaledb_config.bgw_job where id = :job_id;
|
|
\set ON_ERROR_STOP 0
|
|
SELECT add_continuous_aggregate_policy('max_mat_view_timestamp', '15 day', '1 day', '1h'::interval, if_not_exists=>true);
|
|
SELECT add_continuous_aggregate_policy('max_mat_view_timestamp', 'xyz', '1 day', '1h'::interval, if_not_exists=>true);
|
|
\set ON_ERROR_STOP 1
|
|
|
|
DROP MATERIALIZED VIEW max_mat_view_timestamp;
|
|
|
|
--smallint table
|
|
CREATE TABLE smallint_tab (a smallint);
|
|
SELECT table_name FROM create_hypertable('smallint_tab', 'a', chunk_time_interval=> 10);
|
|
CREATE OR REPLACE FUNCTION integer_now_smallint_tab() returns smallint LANGUAGE SQL STABLE as $$ SELECT coalesce(max(a)::smallint, 0::smallint) FROM smallint_tab ; $$;
|
|
SELECT set_integer_now_func('smallint_tab', 'integer_now_smallint_tab');
|
|
|
|
CREATE MATERIALIZED VIEW mat_smallint( a, countb )
|
|
WITH (timescaledb.continuous, timescaledb.materialized_only=true)
|
|
as
|
|
SELECT time_bucket( SMALLINT '1', a) , count(*)
|
|
FROM smallint_tab
|
|
GROUP BY 1 WITH NO DATA;
|
|
\set ON_ERROR_STOP 0
|
|
\set VERBOSITY default
|
|
SELECT add_continuous_aggregate_policy('mat_smallint', 15, 0 , '1 h'::interval);
|
|
SELECT add_continuous_aggregate_policy('mat_smallint', 98898::smallint , 0::smallint, '1 h'::interval);
|
|
SELECT add_continuous_aggregate_policy('mat_smallint', 5::smallint, 10::smallint , '1 h'::interval) as job_id \gset
|
|
\set VERBOSITY terse
|
|
\set ON_ERROR_STOP 1
|
|
SELECT add_continuous_aggregate_policy('mat_smallint', 15::smallint, 0::smallint , '1 h'::interval) as job_id \gset
|
|
INSERT INTO smallint_tab VALUES(5);
|
|
INSERT INTO smallint_tab VALUES(10);
|
|
INSERT INTO smallint_tab VALUES(20);
|
|
CALL run_job(:job_id);
|
|
SELECT * FROM mat_smallint ORDER BY 1;
|
|
|
|
--remove all the data--
|
|
TRUNCATE table smallint_tab;
|
|
CALL refresh_continuous_aggregate('mat_smallint', NULL, NULL);
|
|
SELECT * FROM mat_smallint ORDER BY 1;
|
|
|
|
-- Case 1: overflow by subtracting from PG_INT16_MIN
|
|
--overflow start_interval, end_interval [-32768, -32768)
|
|
SELECT remove_continuous_aggregate_policy('mat_smallint');
|
|
INSERT INTO smallint_tab VALUES( -32768 );
|
|
SELECT integer_now_smallint_tab();
|
|
SELECT add_continuous_aggregate_policy('mat_smallint', 10::smallint, 5::smallint , '1 h'::interval) as job_id \gset
|
|
|
|
\set ON_ERROR_STOP 0
|
|
CALL run_job(:job_id);
|
|
\set ON_ERROR_STOP 1
|
|
SELECT * FROM mat_smallint ORDER BY 1;
|
|
|
|
-- overflow start_interval. now this runs as range is capped [-32768, -32765)
|
|
INSERT INTO smallint_tab VALUES( -32760 );
|
|
SELECT maxval, maxval - 10, maxval -5 FROM integer_now_smallint_tab() as maxval;
|
|
CALL run_job(:job_id);
|
|
SELECT * FROM mat_smallint ORDER BY 1;
|
|
|
|
--remove all the data--
|
|
TRUNCATE table smallint_tab;
|
|
CALL refresh_continuous_aggregate('mat_smallint', NULL, NULL);
|
|
SELECT * FROM mat_smallint ORDER BY 1;
|
|
|
|
-- Case 2: overflow by subtracting from PG_INT16_MAX
|
|
--overflow start and end . will fail as range is [32767, 32767]
|
|
SELECT remove_continuous_aggregate_policy('mat_smallint');
|
|
INSERT INTO smallint_tab VALUES( 32766 );
|
|
INSERT INTO smallint_tab VALUES( 32767 );
|
|
SELECT maxval, maxval - (-1), maxval - (-2) FROM integer_now_smallint_tab() as maxval;
|
|
SELECT add_continuous_aggregate_policy('mat_smallint', -1::smallint, -3::smallint , '1 h'::interval) as job_id \gset
|
|
\set ON_ERROR_STOP 0
|
|
CALL run_job(:job_id);
|
|
\set ON_ERROR_STOP 1
|
|
SELECT * FROM mat_smallint ORDER BY 1;
|
|
|
|
SELECT remove_continuous_aggregate_policy('mat_smallint');
|
|
--overflow end . will work range is [32765, 32767)
|
|
SELECT maxval, maxval - (1), maxval - (-2) FROM integer_now_smallint_tab() as maxval;
|
|
SELECT add_continuous_aggregate_policy('mat_smallint', 1::smallint, -3::smallint , '1 h'::interval) as job_id \gset
|
|
\set ON_ERROR_STOP 0
|
|
CALL run_job(:job_id);
|
|
SELECT * FROM mat_smallint ORDER BY 1;
|
|
|
|
-- tests for interval argument conversions
|
|
--
|
|
\set ON_ERROR_STOP 0
|
|
SELECT add_continuous_aggregate_policy('mat_smallint', 15, 10, '1h'::interval, if_not_exists=>true);
|
|
SELECT add_continuous_aggregate_policy('mat_smallint', '15', 10, '1h'::interval, if_not_exists=>true);
|
|
SELECT add_continuous_aggregate_policy('mat_smallint', '15', '10', '1h'::interval, if_not_exists=>true);
|
|
\set ON_ERROR_STOP 1
|
|
|
|
|
|
--bigint table
|
|
CREATE TABLE bigint_tab (a bigint);
|
|
SELECT table_name FROM create_hypertable('bigint_tab', 'a', chunk_time_interval=> 10);
|
|
CREATE OR REPLACE FUNCTION integer_now_bigint_tab() returns bigint LANGUAGE SQL STABLE as $$ SELECT 20::bigint $$;
|
|
SELECT set_integer_now_func('bigint_tab', 'integer_now_bigint_tab');
|
|
|
|
CREATE MATERIALIZED VIEW mat_bigint( a, countb )
|
|
WITH (timescaledb.continuous, timescaledb.materialized_only=true)
|
|
as
|
|
SELECT time_bucket( BIGINT '1', a) , count(*)
|
|
FROM bigint_tab
|
|
GROUP BY 1 WITH NO DATA;
|
|
\set ON_ERROR_STOP 0
|
|
SELECT add_continuous_aggregate_policy('mat_bigint', 5::bigint, 10::bigint , '1 h'::interval) ;
|
|
\set ON_ERROR_STOP 1
|
|
SELECT add_continuous_aggregate_policy('mat_bigint', 15::bigint, 0::bigint , '1 h'::interval) as job_mid \gset
|
|
INSERT INTO bigint_tab VALUES(5);
|
|
INSERT INTO bigint_tab VALUES(10);
|
|
INSERT INTO bigint_tab VALUES(20);
|
|
CALL run_job(:job_mid);
|
|
SELECT * FROM mat_bigint;
|
|
|
|
-- test NULL for end
|
|
SELECT remove_continuous_aggregate_policy('mat_bigint');
|
|
SELECT add_continuous_aggregate_policy('mat_bigint', 1::smallint, NULL , '1 h'::interval) as job_id \gset
|
|
INSERT INTO bigint_tab VALUES(500);
|
|
CALL run_job(:job_id);
|
|
SELECT * FROM mat_bigint WHERE a>100 ORDER BY 1;
|
|
|
|
ALTER MATERIALIZED VIEW mat_bigint SET (timescaledb.compress);
|
|
ALTER MATERIALIZED VIEW mat_smallint SET (timescaledb.compress);
|
|
\set ON_ERROR_STOP 0
|
|
SELECT add_compression_policy('mat_smallint', 0::smallint);
|
|
SELECT add_compression_policy('mat_smallint', -4::smallint);
|
|
SELECT add_compression_policy('mat_bigint', 0::bigint);
|
|
\set ON_ERROR_STOP 1
|
|
SELECT add_compression_policy('mat_smallint', 5::smallint);
|
|
SELECT add_compression_policy('mat_bigint', 20::bigint);
|
|
|
|
-- end of coverage tests
|
|
|
|
--TEST continuous aggregate + compression policy on caggs
|
|
CREATE TABLE metrics (
|
|
time timestamptz NOT NULL,
|
|
device_id int,
|
|
device_id_peer int,
|
|
v0 int,
|
|
v1 int,
|
|
v2 float,
|
|
v3 float
|
|
);
|
|
|
|
SELECT create_hypertable('metrics', 'time');
|
|
|
|
INSERT INTO metrics (time, device_id, device_id_peer, v0, v1, v2, v3)
|
|
SELECT time,
|
|
device_id,
|
|
0,
|
|
device_id + 1,
|
|
device_id + 2,
|
|
0.5,
|
|
NULL
|
|
FROM generate_series('2000-01-01 0:00:00+0'::timestamptz, '2000-01-02 23:55:00+0', '20m') gtime (time),
|
|
generate_series(1, 2, 1) gdevice (device_id);
|
|
|
|
ALTER TABLE metrics SET ( timescaledb.compress );
|
|
SELECT compress_chunk(ch) FROM show_chunks('metrics') ch;
|
|
|
|
CREATE MATERIALIZED VIEW metrics_cagg WITH (timescaledb.continuous,
|
|
timescaledb.materialized_only = true)
|
|
AS
|
|
SELECT time_bucket('1 day', time) as dayb, device_id,
|
|
sum(v0), avg(v3)
|
|
FROM metrics
|
|
GROUP BY 1, 2
|
|
WITH NO DATA;
|
|
|
|
--can set compression policy only after setting up refresh policy --
|
|
\set ON_ERROR_STOP 0
|
|
SELECT add_compression_policy('metrics_cagg', '1 day'::interval);
|
|
|
|
--can set compression policy only after enabling compression --
|
|
SELECT add_continuous_aggregate_policy('metrics_cagg', '7 day'::interval, '1 day'::interval, '1 h'::interval) as "REFRESH_JOB" \gset
|
|
SELECT add_compression_policy('metrics_cagg', '8 day'::interval) AS "COMP_JOB" ;
|
|
\set ON_ERROR_STOP 1
|
|
|
|
ALTER MATERIALIZED VIEW metrics_cagg SET (timescaledb.compress);
|
|
|
|
SELECT add_compression_policy('metrics_cagg', '8 day'::interval) AS "COMP_JOB" ;
|
|
SELECT remove_compression_policy('metrics_cagg');
|
|
SELECT add_compression_policy('metrics_cagg', '8 day'::interval) AS "COMP_JOB" \gset
|
|
|
|
--verify that jobs were added for the policies ---
|
|
SELECT materialization_hypertable_schema AS "MAT_SCHEMA_NAME",
|
|
materialization_hypertable_name AS "MAT_TABLE_NAME",
|
|
materialization_hypertable_schema || '.' || materialization_hypertable_name AS "MAT_NAME"
|
|
FROM timescaledb_information.continuous_aggregates
|
|
WHERE view_name = 'metrics_cagg' \gset
|
|
|
|
SELECT count(*) FROM timescaledb_information.jobs
|
|
WHERE hypertable_name = :'MAT_TABLE_NAME';
|
|
|
|
--exec the cagg compression job --
|
|
CALL refresh_continuous_aggregate('metrics_cagg', NULL, '2001-02-01 00:00:00+0');
|
|
CALL run_job(:COMP_JOB);
|
|
SELECT count(*), count(*) FILTER ( WHERE is_compressed is TRUE )
|
|
FROM timescaledb_information.chunks
|
|
WHERE hypertable_name = :'MAT_TABLE_NAME' ORDER BY 1;
|
|
|
|
--add some new data into metrics_cagg so that cagg policy job has something to do
|
|
INSERT INTO metrics (time, device_id, device_id_peer, v0, v1, v2, v3)
|
|
SELECT now() - '5 day'::interval, 102, 0, 10, 10, 10, 10;
|
|
CALL run_job(:REFRESH_JOB);
|
|
--now we have a new chunk and it is not compressed
|
|
SELECT count(*), count(*) FILTER ( WHERE is_compressed is TRUE )
|
|
FROM timescaledb_information.chunks
|
|
WHERE hypertable_name = :'MAT_TABLE_NAME' ORDER BY 1;
|
|
|
|
--verify that both jobs are dropped when view is dropped
|
|
DROP MATERIALIZED VIEW metrics_cagg;
|
|
|
|
SELECT count(*) FROM timescaledb_information.jobs
|
|
WHERE hypertable_name = :'MAT_TABLE_NAME';
|
|
|
|
-- add test case for issue 4252
|
|
CREATE TABLE IF NOT EXISTS sensor_data(
|
|
time TIMESTAMPTZ NOT NULL,
|
|
sensor_id INTEGER,
|
|
temperature DOUBLE PRECISION,
|
|
cpu DOUBLE PRECISION);
|
|
|
|
SELECT create_hypertable('sensor_data','time');
|
|
|
|
INSERT INTO sensor_data(time, sensor_id, cpu, temperature)
|
|
SELECT
|
|
time,
|
|
sensor_id,
|
|
extract(dow from time) AS cpu,
|
|
extract(doy from time) AS temperature
|
|
FROM
|
|
generate_series('2022-05-05'::timestamp at time zone 'UTC' - interval '6 weeks', '2022-05-05'::timestamp at time zone 'UTC', interval '5 hours') as g1(time),
|
|
generate_series(1,1000,1) as g2(sensor_id);
|
|
|
|
CREATE materialized view deals_best_weekly
|
|
WITH (timescaledb.continuous) AS
|
|
SELECT
|
|
time_bucket('7 days', "time") AS bucket,
|
|
avg(temperature) AS avg_temp,
|
|
max(cpu) AS max_rating
|
|
FROM sensor_data
|
|
GROUP BY bucket
|
|
WITH NO DATA;
|
|
|
|
CREATE materialized view deals_best_daily
|
|
WITH (timescaledb.continuous) AS
|
|
SELECT
|
|
time_bucket('1 day', "time") AS bucket,
|
|
avg(temperature) AS avg_temp,
|
|
max(cpu) AS max_rating
|
|
FROM sensor_data
|
|
GROUP BY bucket
|
|
WITH NO DATA;
|
|
|
|
ALTER materialized view deals_best_weekly set (timescaledb.materialized_only=true);
|
|
ALTER materialized view deals_best_daily set (timescaledb.materialized_only=true);
|
|
|
|
-- we have data from 6 weeks before to May 5 2022 (Thu)
|
|
CALL refresh_continuous_aggregate('deals_best_weekly', '2022-04-24', '2022-05-03');
|
|
SELECT * FROM deals_best_weekly;
|
|
CALL refresh_continuous_aggregate('deals_best_daily', '2022-04-20', '2022-05-04');
|
|
SELECT * FROM deals_best_daily ORDER BY bucket LIMIT 2;
|
|
-- expect to get an up-to-date notice
|
|
CALL refresh_continuous_aggregate('deals_best_weekly', '2022-04-24', '2022-05-05');
|
|
SELECT * FROM deals_best_weekly;
|