1-- This file and its contents are licensed under the Timescale License. 2-- Please see the included NOTICE for copyright information and 3-- LICENSE-TIMESCALE for a copy of the license. 4 5-- test add and remove refresh policy apis 6 7SET ROLE :ROLE_DEFAULT_PERM_USER; 8 9 10--TEST1 --- 11--basic test with count 12CREATE TABLE int_tab (a integer, b integer, c integer); 13SELECT table_name FROM create_hypertable('int_tab', 'a', chunk_time_interval=> 10); 14 15INSERT INTO int_tab VALUES( 3 , 16 , 20); 16INSERT INTO int_tab VALUES( 1 , 10 , 20); 17INSERT INTO int_tab VALUES( 1 , 11 , 20); 18INSERT INTO int_tab VALUES( 1 , 12 , 20); 19INSERT INTO int_tab VALUES( 1 , 13 , 20); 20INSERT INTO int_tab VALUES( 1 , 14 , 20); 21INSERT INTO int_tab VALUES( 2 , 14 , 20); 22INSERT INTO int_tab VALUES( 2 , 15 , 20); 23INSERT INTO int_tab VALUES( 2 , 16 , 20); 24 25CREATE OR REPLACE FUNCTION integer_now_int_tab() returns int LANGUAGE SQL STABLE as $$ SELECT coalesce(max(a), 0) FROM int_tab $$; 26SELECT set_integer_now_func('int_tab', 'integer_now_int_tab'); 27 28 29CREATE MATERIALIZED VIEW mat_m1( a, countb ) 30WITH (timescaledb.continuous, timescaledb.materialized_only=true) 31as 32SELECT a, count(b) 33FROM int_tab 34GROUP BY time_bucket(1, a), a WITH NO DATA; 35 36\c :TEST_DBNAME :ROLE_SUPERUSER 37DELETE FROM _timescaledb_config.bgw_job WHERE TRUE; 38 39SET ROLE :ROLE_DEFAULT_PERM_USER; 40SELECT count(*) FROM _timescaledb_config.bgw_job; 41 42\set ON_ERROR_STOP 0 43\set VERBOSITY default 44SELECT add_continuous_aggregate_policy('int_tab', '1 day'::interval, 10 , '1 h'::interval); 45SELECT add_continuous_aggregate_policy('mat_m1', '1 day'::interval, 10 , '1 h'::interval); 46SELECT add_continuous_aggregate_policy('mat_m1', '1 day'::interval, 10 ); 47SELECT add_continuous_aggregate_policy('mat_m1', 10, '1 day'::interval, '1 h'::interval); 48--start_interval < end_interval 49SELECT add_continuous_aggregate_policy('mat_m1', 5, 10, '1h'::interval); 50--refresh window less than two buckets 51SELECT add_continuous_aggregate_policy('mat_m1', 11, 10, '1h'::interval); 52SELECT add_continuous_aggregate_policy('mat_m1', 20, 10, '1h'::interval) as job_id \gset 53 54--adding again should warn/error 55SELECT add_continuous_aggregate_policy('mat_m1', 20, 10, '1h'::interval, if_not_exists=>false); 56SELECT add_continuous_aggregate_policy('mat_m1', 20, 15, '1h'::interval, if_not_exists=>true); 57SELECT add_continuous_aggregate_policy('mat_m1', 20, 10, '1h'::interval, if_not_exists=>true); 58 59-- modify config and try to add, should error out 60SELECT config FROM _timescaledb_config.bgw_job where id = :job_id; 61SELECT hypertable_id as mat_id FROM _timescaledb_config.bgw_job where id = :job_id \gset 62\set VERBOSITY terse 63\set ON_ERROR_STOP 1 64 65\c :TEST_DBNAME :ROLE_SUPERUSER 66UPDATE _timescaledb_config.bgw_job 67SET config = jsonb_build_object('mat_hypertable_id', :mat_id) 68WHERE id = :job_id; 69SET ROLE :ROLE_DEFAULT_PERM_USER; 70SELECT config FROM _timescaledb_config.bgw_job where id = :job_id; 71 72\set ON_ERROR_STOP 0 73\set VERBOSITY default 74SELECT add_continuous_aggregate_policy('mat_m1', 20, 10, '1h'::interval, if_not_exists=>true); 75 76SELECT remove_continuous_aggregate_policy('int_tab'); 77SELECT remove_continuous_aggregate_policy('mat_m1'); 78--this one will fail 79SELECT remove_continuous_aggregate_policy('mat_m1'); 80SELECT remove_continuous_aggregate_policy('mat_m1', if_not_exists=>true); 81 82--now try to add a policy as a different user than the one that created the cagg 83--should fail 84SET ROLE :ROLE_DEFAULT_PERM_USER_2; 85SELECT add_continuous_aggregate_policy('mat_m1', 20, 10, '1h'::interval) as job_id ; 86\set VERBOSITY terse 87\set ON_ERROR_STOP 1 88 89SET ROLE :ROLE_DEFAULT_PERM_USER; 90DROP MATERIALIZED VIEW mat_m1; 91 92--- code coverage tests : add policy for timestamp and date based table --- 93CREATE TABLE continuous_agg_max_mat_date(time DATE); 94SELECT create_hypertable('continuous_agg_max_mat_date', 'time'); 95CREATE MATERIALIZED VIEW max_mat_view_date 96 WITH (timescaledb.continuous, timescaledb.materialized_only=true) 97 AS SELECT time_bucket('7 days', time) 98 FROM continuous_agg_max_mat_date 99 GROUP BY 1 WITH NO DATA; 100 101\set ON_ERROR_STOP 0 102\set VERBOSITY default 103SELECT add_continuous_aggregate_policy('max_mat_view_date', '2 days', 10, '1 day'::interval); 104--start_interval < end_interval 105SELECT add_continuous_aggregate_policy('max_mat_view_date', '1 day'::interval, '2 days'::interval , '1 day'::interval) ; 106--interval less than two buckets 107SELECT add_continuous_aggregate_policy('max_mat_view_date', '7 days', '1 day', '1 day'::interval); 108SELECT add_continuous_aggregate_policy('max_mat_view_date', '14 days', '1 day', '1 day'::interval); 109SELECT add_continuous_aggregate_policy('max_mat_view_date', '13 days', '-10 hours', '1 day'::interval); 110\set VERBOSITY terse 111\set ON_ERROR_STOP 1 112 113-- Negative start offset gives two bucket window: 114SELECT add_continuous_aggregate_policy('max_mat_view_date', '13 days', '-1 day', '1 day'::interval); 115SELECT remove_continuous_aggregate_policy('max_mat_view_date'); 116-- Both offsets NULL: 117SELECT add_continuous_aggregate_policy('max_mat_view_date', NULL, NULL, '1 day'::interval); 118SELECT remove_continuous_aggregate_policy('max_mat_view_date'); 119 120SELECT add_continuous_aggregate_policy('max_mat_view_date', '15 days', '1 day', '1 day'::interval) as job_id \gset 121SELECT config FROM _timescaledb_config.bgw_job 122WHERE id = :job_id; 123 124INSERT INTO continuous_agg_max_mat_date 125 SELECT generate_series('2019-09-01'::date, '2019-09-10'::date, '1 day'); 126--- to prevent NOTICES set message level to warning 127SET client_min_messages TO warning; 128CALL run_job(:job_id); 129RESET client_min_messages; 130DROP MATERIALIZED VIEW max_mat_view_date; 131 132CREATE TABLE continuous_agg_timestamp(time TIMESTAMP); 133SELECT create_hypertable('continuous_agg_timestamp', 'time'); 134 135CREATE MATERIALIZED VIEW max_mat_view_timestamp 136 WITH (timescaledb.continuous, timescaledb.materialized_only=true) 137 AS SELECT time_bucket('7 days', time) 138 FROM continuous_agg_timestamp 139 GROUP BY 1 WITH NO DATA; 140 141--the start offset overflows the smallest time value, but is capped at 142--the min value 143SELECT add_continuous_aggregate_policy('max_mat_view_timestamp', '1000000 years', '1 day' , '1 h'::interval); 144SELECT remove_continuous_aggregate_policy('max_mat_view_timestamp'); 145 146\set ON_ERROR_STOP 0 147\set VERBOSITY default 148--start and end offset capped at the lowest time value, which means 149--zero size window 150SELECT add_continuous_aggregate_policy('max_mat_view_timestamp', '1000000 years', '900000 years' , '1 h'::interval); 151SELECT add_continuous_aggregate_policy('max_mat_view_timestamp', '301 days', '10 months' , '1 h'::interval); 152\set VERBOSITY terse 153\set ON_ERROR_STOP 1 154 155SELECT add_continuous_aggregate_policy('max_mat_view_timestamp', '15 days', '1 h'::interval , '1 h'::interval) as job_id \gset 156 157--- to prevent NOTICES set message level to warning 158SET client_min_messages TO warning; 159CALL run_job(:job_id); 160RESET client_min_messages ; 161 162SELECT config FROM _timescaledb_config.bgw_job 163WHERE id = :job_id; 164 165\c :TEST_DBNAME :ROLE_SUPERUSER 166UPDATE _timescaledb_config.bgw_job 167SET config = jsonb_build_object('mat_hypertable_id', :mat_id) 168WHERE id = :job_id; 169 170SET ROLE :ROLE_DEFAULT_PERM_USER; 171SELECT config FROM _timescaledb_config.bgw_job where id = :job_id; 172\set ON_ERROR_STOP 0 173SELECT add_continuous_aggregate_policy('max_mat_view_timestamp', '15 day', '1 day', '1h'::interval, if_not_exists=>true); 174SELECT add_continuous_aggregate_policy('max_mat_view_timestamp', 'xyz', '1 day', '1h'::interval, if_not_exists=>true); 175\set ON_ERROR_STOP 1 176 177DROP MATERIALIZED VIEW max_mat_view_timestamp; 178 179--smallint table 180CREATE TABLE smallint_tab (a smallint); 181SELECT table_name FROM create_hypertable('smallint_tab', 'a', chunk_time_interval=> 10); 182CREATE OR REPLACE FUNCTION integer_now_smallint_tab() returns smallint LANGUAGE SQL STABLE as $$ SELECT coalesce(max(a)::smallint, 0::smallint) FROM smallint_tab ; $$; 183SELECT set_integer_now_func('smallint_tab', 'integer_now_smallint_tab'); 184 185CREATE MATERIALIZED VIEW mat_smallint( a, countb ) 186WITH (timescaledb.continuous, timescaledb.materialized_only=true) 187as 188SELECT time_bucket( SMALLINT '1', a) , count(*) 189FROM smallint_tab 190GROUP BY 1 WITH NO DATA; 191\set ON_ERROR_STOP 0 192\set VERBOSITY default 193SELECT add_continuous_aggregate_policy('mat_smallint', 15, 0 , '1 h'::interval); 194SELECT add_continuous_aggregate_policy('mat_smallint', 98898::smallint , 0::smallint, '1 h'::interval); 195SELECT add_continuous_aggregate_policy('mat_smallint', 5::smallint, 10::smallint , '1 h'::interval) as job_id \gset 196\set VERBOSITY terse 197\set ON_ERROR_STOP 1 198SELECT add_continuous_aggregate_policy('mat_smallint', 15::smallint, 0::smallint , '1 h'::interval) as job_id \gset 199INSERT INTO smallint_tab VALUES(5); 200INSERT INTO smallint_tab VALUES(10); 201INSERT INTO smallint_tab VALUES(20); 202CALL run_job(:job_id); 203SELECT * FROM mat_smallint ORDER BY 1; 204 205--remove all the data-- 206TRUNCATE table smallint_tab; 207CALL refresh_continuous_aggregate('mat_smallint', NULL, NULL); 208SELECT * FROM mat_smallint ORDER BY 1; 209 210-- Case 1: overflow by subtracting from PG_INT16_MIN 211--overflow start_interval, end_interval [-32768, -32768) 212SELECT remove_continuous_aggregate_policy('mat_smallint'); 213INSERT INTO smallint_tab VALUES( -32768 ); 214SELECT integer_now_smallint_tab(); 215SELECT add_continuous_aggregate_policy('mat_smallint', 10::smallint, 5::smallint , '1 h'::interval) as job_id \gset 216 217\set ON_ERROR_STOP 0 218CALL run_job(:job_id); 219\set ON_ERROR_STOP 1 220SELECT * FROM mat_smallint ORDER BY 1; 221 222-- overflow start_interval. now this runs as range is capped [-32768, -32765) 223INSERT INTO smallint_tab VALUES( -32760 ); 224SELECT maxval, maxval - 10, maxval -5 FROM integer_now_smallint_tab() as maxval; 225CALL run_job(:job_id); 226SELECT * FROM mat_smallint ORDER BY 1; 227 228--remove all the data-- 229TRUNCATE table smallint_tab; 230CALL refresh_continuous_aggregate('mat_smallint', NULL, NULL); 231SELECT * FROM mat_smallint ORDER BY 1; 232 233-- Case 2: overflow by subtracting from PG_INT16_MAX 234--overflow start and end . will fail as range is [32767, 32767] 235SELECT remove_continuous_aggregate_policy('mat_smallint'); 236INSERT INTO smallint_tab VALUES( 32766 ); 237INSERT INTO smallint_tab VALUES( 32767 ); 238SELECT maxval, maxval - (-1), maxval - (-2) FROM integer_now_smallint_tab() as maxval; 239SELECT add_continuous_aggregate_policy('mat_smallint', -1::smallint, -3::smallint , '1 h'::interval) as job_id \gset 240\set ON_ERROR_STOP 0 241CALL run_job(:job_id); 242\set ON_ERROR_STOP 1 243SELECT * FROM mat_smallint ORDER BY 1; 244 245SELECT remove_continuous_aggregate_policy('mat_smallint'); 246--overflow end . will work range is [32765, 32767) 247SELECT maxval, maxval - (1), maxval - (-2) FROM integer_now_smallint_tab() as maxval; 248SELECT add_continuous_aggregate_policy('mat_smallint', 1::smallint, -3::smallint , '1 h'::interval) as job_id \gset 249\set ON_ERROR_STOP 0 250CALL run_job(:job_id); 251SELECT * FROM mat_smallint ORDER BY 1; 252 253-- tests for interval argument conversions 254-- 255\set ON_ERROR_STOP 0 256SELECT add_continuous_aggregate_policy('mat_smallint', 15, 10, '1h'::interval, if_not_exists=>true); 257SELECT add_continuous_aggregate_policy('mat_smallint', '15', 10, '1h'::interval, if_not_exists=>true); 258SELECT add_continuous_aggregate_policy('mat_smallint', '15', '10', '1h'::interval, if_not_exists=>true); 259\set ON_ERROR_STOP 1 260 261DROP MATERIALIZED VIEW mat_smallint; 262DROP TABLE smallint_tab CASCADE; 263 264--bigint table 265CREATE TABLE bigint_tab (a bigint); 266SELECT table_name FROM create_hypertable('bigint_tab', 'a', chunk_time_interval=> 10); 267CREATE OR REPLACE FUNCTION integer_now_bigint_tab() returns bigint LANGUAGE SQL STABLE as $$ SELECT 20::bigint $$; 268SELECT set_integer_now_func('bigint_tab', 'integer_now_bigint_tab'); 269 270CREATE MATERIALIZED VIEW mat_bigint( a, countb ) 271WITH (timescaledb.continuous, timescaledb.materialized_only=true) 272as 273SELECT time_bucket( BIGINT '1', a) , count(*) 274FROM bigint_tab 275GROUP BY 1 WITH NO DATA; 276\set ON_ERROR_STOP 0 277SELECT add_continuous_aggregate_policy('mat_bigint', 5::bigint, 10::bigint , '1 h'::interval) ; 278\set ON_ERROR_STOP 1 279SELECT add_continuous_aggregate_policy('mat_bigint', 15::bigint, 0::bigint , '1 h'::interval) as job_mid \gset 280INSERT INTO bigint_tab VALUES(5); 281INSERT INTO bigint_tab VALUES(10); 282INSERT INTO bigint_tab VALUES(20); 283CALL run_job(:job_mid); 284SELECT * FROM mat_bigint; 285 286-- test NULL for end 287SELECT remove_continuous_aggregate_policy('mat_bigint'); 288SELECT add_continuous_aggregate_policy('mat_bigint', 1::smallint, NULL , '1 h'::interval) as job_id \gset 289INSERT INTO bigint_tab VALUES(500); 290CALL run_job(:job_id); 291SELECT * FROM mat_bigint WHERE a>100 ORDER BY 1; 292 293-- end of coverage tests 294