From db0e210b8fb09dd8f61f96d90d992b062ac94b9e Mon Sep 17 00:00:00 2001 From: Sven Klemm Date: Mon, 28 Sep 2020 11:05:00 +0200 Subject: [PATCH] Block REFRESH MATERIALIZED VIEW on caggs --- src/process_utility.c | 19 +++++------- test/sql/updates/post.continuous_aggs.sql | 2 +- test/sql/updates/post.continuous_aggs.v2.sql | 4 +-- test/sql/updates/setup.continuous_aggs.sql | 7 +++++ test/sql/updates/setup.continuous_aggs.v2.sql | 30 +++++++++++++++---- tsl/test/expected/continuous_aggs_refresh.out | 19 ++---------- tsl/test/sql/continuous_aggs_refresh.sql | 7 ++--- 7 files changed, 47 insertions(+), 41 deletions(-) diff --git a/src/process_utility.c b/src/process_utility.c index 0d6b0b12e..1a7e559d6 100644 --- a/src/process_utility.c +++ b/src/process_utility.c @@ -3397,24 +3397,21 @@ process_refresh_mat_view_start(ProcessUtilityArgs *args) RefreshMatViewStmt *stmt = castNode(RefreshMatViewStmt, args->parsetree); Oid view_relid = RangeVarGetRelid(stmt->relation, NoLock, true); const ContinuousAgg *cagg; - LOCAL_FCINFO(fcinfo, 3); if (!OidIsValid(view_relid)) return DDL_CONTINUE; cagg = ts_continuous_agg_find_by_relid(view_relid); - if (NULL == cagg) - return DDL_CONTINUE; + if (cagg) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("operation not supported on continuous aggregate"), + errdetail("A continuous aggregate does not support REFRESH MATERIALIZED VIEW."), + errhint("Use \"refresh_continuous_aggregate\" or set up a policy to refresh the " + "continuous aggregate."))); - PreventInTransactionBlock(args->context == PROCESS_UTILITY_TOPLEVEL, "REFRESH"); - - FC_SET_ARG(fcinfo, 0, ObjectIdGetDatum(view_relid)); - FC_SET_NULL(fcinfo, 1); - FC_SET_NULL(fcinfo, 2); - ts_cm_functions->continuous_agg_refresh(fcinfo); - - return DDL_DONE; + return DDL_CONTINUE; } /* diff --git a/test/sql/updates/post.continuous_aggs.sql b/test/sql/updates/post.continuous_aggs.sql index c16efb3db..e6bea87a0 100644 --- a/test/sql/updates/post.continuous_aggs.sql +++ b/test/sql/updates/post.continuous_aggs.sql @@ -13,7 +13,7 @@ SELECT generate_series('2017-12-01 00:00'::timestamp, '2017-12-31 00:00'::timest SELECT * FROM mat_before ORDER BY bucket, location; -REFRESH MATERIALIZED VIEW mat_before; +CALL refresh_continuous_aggregate('mat_before',NULL,NULL); --the max of the temp for the POR should now be 165 SELECT * FROM mat_before ORDER BY bucket, location; diff --git a/test/sql/updates/post.continuous_aggs.v2.sql b/test/sql/updates/post.continuous_aggs.v2.sql index b86f9da75..3c1470c6f 100644 --- a/test/sql/updates/post.continuous_aggs.v2.sql +++ b/test/sql/updates/post.continuous_aggs.v2.sql @@ -8,7 +8,7 @@ SELECT * FROM cagg.realtime_mat ORDER BY bucket, location; -REFRESH MATERIALIZED VIEW cagg.realtime_mat; +CALL refresh_continuous_aggregate('cagg.realtime_mat',NULL,NULL); SELECT * FROM cagg.realtime_mat ORDER BY bucket, location; @@ -17,5 +17,5 @@ SELECT view_name, schedule_interval, materialized_only, materialization_hypertab SELECT maxtemp FROM mat_ignoreinval ORDER BY 1; SELECT count(*) FROM mat_inval; -REFRESH MATERIALIZED VIEW mat_inval; +CALL refresh_continuous_aggregate('mat_inval',NULL,NULL); SELECT count(*) FROM mat_inval; diff --git a/test/sql/updates/setup.continuous_aggs.sql b/test/sql/updates/setup.continuous_aggs.sql index 3d05015ad..80aa1e9d0 100644 --- a/test/sql/updates/setup.continuous_aggs.sql +++ b/test/sql/updates/setup.continuous_aggs.sql @@ -130,4 +130,11 @@ BEGIN END IF; END $$; +-- have to use psql conditional here because the procedure call can't be in transaction +SELECT extversion < '2.0.0' AS has_refresh_mat_view from pg_extension WHERE extname = 'timescaledb' \gset +\if :has_refresh_mat_view REFRESH MATERIALIZED VIEW mat_before; +\else +CALL refresh_continuous_aggregate('mat_before',NULL,NULL); +\endif + diff --git a/test/sql/updates/setup.continuous_aggs.v2.sql b/test/sql/updates/setup.continuous_aggs.v2.sql index 923ffe98e..cb1ac9df0 100644 --- a/test/sql/updates/setup.continuous_aggs.v2.sql +++ b/test/sql/updates/setup.continuous_aggs.v2.sql @@ -2,6 +2,8 @@ -- Please see the included NOTICE for copyright information and -- LICENSE-APACHE for a copy of the license. +SELECT extversion < '2.0.0' AS has_refresh_mat_view from pg_extension WHERE extname = 'timescaledb' \gset + CREATE TYPE custom_type AS (high int, low int); CREATE TABLE conditions_before ( @@ -121,12 +123,16 @@ BEGIN FROM conditions_before GROUP BY bucket, location HAVING min(location) >= 'NYC' and avg(temperature) > 2 WITH NO DATA; - PERFORM add_continuous_aggregate_policy('mat_before', NULL, '-30 days'::interval, '336 h'); + PERFORM add_continuous_aggregate_policy('mat_before', NULL, '-30 days'::interval, '336 h'); END IF; END $$; +\if :has_refresh_mat_view REFRESH MATERIALIZED VIEW mat_before; - +\else +CALL refresh_continuous_aggregate('mat_before',NULL,NULL); +\endif + -- we create separate schema for realtime agg since we dump all view definitions in public schema -- but realtime agg view definition is not stable across versions CREATE SCHEMA cagg; @@ -225,11 +231,15 @@ BEGIN FROM conditions_before GROUP BY bucket, location HAVING min(location) >= 'NYC' and avg(temperature) > 2 WITH NO DATA; - PERFORM add_continuous_aggregate_policy('cagg.realtime_mat', NULL, '-30 days'::interval, '336 h'); + PERFORM add_continuous_aggregate_policy('cagg.realtime_mat', NULL, '-30 days'::interval, '336 h'); END IF; END $$; +\if :has_refresh_mat_view REFRESH MATERIALIZED VIEW cagg.realtime_mat; +\else +CALL refresh_continuous_aggregate('cagg.realtime_mat',NULL,NULL); +\endif -- test ignore_invalidation_older_than migration -- DO LANGUAGE PLPGSQL $$ @@ -240,9 +250,9 @@ BEGIN IF ts_version < '2.0.0' THEN CREATE VIEW mat_ignoreinval - WITH ( timescaledb.continuous, timescaledb.materialized_only=true, + WITH ( timescaledb.continuous, timescaledb.materialized_only=true, timescaledb.refresh_lag='-30 day', - timescaledb.ignore_invalidation_older_than='30 days', + timescaledb.ignore_invalidation_older_than='30 days', timescaledb.max_interval_per_job = '100000 days') AS SELECT time_bucket('1 week', timec) as bucket, @@ -258,11 +268,15 @@ BEGIN FROM conditions_before GROUP BY bucket WITH NO DATA; - PERFORM add_continuous_aggregate_policy('mat_ignoreinval', '30 days'::interval, '-30 days'::interval, '336 h'); + PERFORM add_continuous_aggregate_policy('mat_ignoreinval', '30 days'::interval, '-30 days'::interval, '336 h'); END IF; END $$; +\if :has_refresh_mat_view REFRESH MATERIALIZED VIEW mat_ignoreinval; +\else +CALL refresh_continuous_aggregate('mat_ignoreinval',NULL,NULL); +\endif -- test new data beyond the invalidation threshold is properly handled -- CREATE TABLE inval_test (time TIMESTAMPTZ, location TEXT, temperature DOUBLE PRECISION); @@ -304,7 +318,11 @@ BEGIN END IF; END $$; +\if :has_refresh_mat_view REFRESH MATERIALIZED VIEW mat_inval; +\else +CALL refresh_continuous_aggregate('mat_inval',NULL,NULL); +\endif INSERT INTO inval_test SELECT generate_series('2118-12-01 00:00'::timestamp, '2118-12-20 00:00'::timestamp, '1 day'), 'POR', generate_series(135.25, 140.0, 0.25); diff --git a/tsl/test/expected/continuous_aggs_refresh.out b/tsl/test/expected/continuous_aggs_refresh.out index 880187d3e..4bffef469 100644 --- a/tsl/test/expected/continuous_aggs_refresh.out +++ b/tsl/test/expected/continuous_aggs_refresh.out @@ -402,25 +402,12 @@ SELECT * FROM weekly_temp_with_data; Sun May 03 17:00:00 2020 PDT | 3 | 19 (8 rows) --- Test that REFRESH MATERIALIZED VIEW works as an alternative to --- refresh_continuous_aggregate() +\set ON_ERROR_STOP 0 +-- REFRESH MATERIALIZED VIEW is blocked on continuous aggregates REFRESH MATERIALIZED VIEW weekly_temp_without_data; -SELECT * FROM weekly_temp_without_data; - day | device | avg_temp -------------------------------+--------+------------------ - Sun Apr 26 17:00:00 2020 PDT | 3 | 21.5631067961165 - Sun Apr 26 17:00:00 2020 PDT | 1 | 17.2474226804124 - Sun May 03 17:00:00 2020 PDT | 0 | 16.7659574468085 - Sun May 03 17:00:00 2020 PDT | 1 | 22.7272727272727 - Sun Apr 26 17:00:00 2020 PDT | 0 | 17.8181818181818 - Sun Apr 26 17:00:00 2020 PDT | 2 | 18.9803921568627 - Sun May 03 17:00:00 2020 PDT | 2 | 15.811320754717 - Sun May 03 17:00:00 2020 PDT | 3 | 19 -(8 rows) - +ERROR: operation not supported on continuous aggregate -- These should fail since we do not allow refreshing inside a -- transaction, not even as part of CREATE MATERIALIZED VIEW. -\set ON_ERROR_STOP 0 DO LANGUAGE PLPGSQL $$ BEGIN CREATE MATERIALIZED VIEW weekly_conditions WITH (timescaledb.continuous, diff --git a/tsl/test/sql/continuous_aggs_refresh.sql b/tsl/test/sql/continuous_aggs_refresh.sql index 7ca26f2a5..000af184d 100644 --- a/tsl/test/sql/continuous_aggs_refresh.sql +++ b/tsl/test/sql/continuous_aggs_refresh.sql @@ -237,15 +237,12 @@ GROUP BY 1,2 WITH DATA; SELECT * FROM weekly_temp_without_data; SELECT * FROM weekly_temp_with_data; --- Test that REFRESH MATERIALIZED VIEW works as an alternative to --- refresh_continuous_aggregate() +\set ON_ERROR_STOP 0 +-- REFRESH MATERIALIZED VIEW is blocked on continuous aggregates REFRESH MATERIALIZED VIEW weekly_temp_without_data; -SELECT * FROM weekly_temp_without_data; - -- These should fail since we do not allow refreshing inside a -- transaction, not even as part of CREATE MATERIALIZED VIEW. -\set ON_ERROR_STOP 0 DO LANGUAGE PLPGSQL $$ BEGIN CREATE MATERIALIZED VIEW weekly_conditions WITH (timescaledb.continuous,