timescaledb/sql/updates/post-update.sql
Nikhil 8aaef4ae14 Fix update tests to handle sequences
The post-update script was handling preserving initprivs for newly
added catalog tables and views. However, newly added catalog sequences
need separate handling otherwise update tests start failing. We also
now grant privileges for all future sequences in the update tests.

In passing, default the PG_VERSION in the update tests to 12 since we
don't work with PG11 anymore.
2021-06-21 13:22:08 +05:30

92 lines
4.0 KiB
SQL

-- needed post 1.7.0 to fixup continuous aggregates created in 1.7.0 ---
DO $$
DECLARE
vname regclass;
materialized_only bool;
altercmd text;
ts_version TEXT;
BEGIN
SELECT extversion INTO ts_version FROM pg_extension WHERE extname = 'timescaledb';
FOR vname, materialized_only IN select format('%I.%I', cagg.user_view_schema, cagg.user_view_name)::regclass, cagg.materialized_only from _timescaledb_catalog.continuous_agg cagg
LOOP
-- the cast from oid to text returns
-- quote_qualified_identifier (see regclassout).
--
-- We use the if statement to handle pre-2.0 as well as
-- post-2.0. This could be turned into a procedure if we want
-- to have something more generic, but right now it is just
-- this case.
IF ts_version < '2.0.0' THEN
altercmd := format('ALTER VIEW %s SET (timescaledb.materialized_only=%L) ', vname::text, materialized_only);
ELSE
altercmd := format('ALTER MATERIALIZED VIEW %s SET (timescaledb.materialized_only=%L) ', vname::text, materialized_only);
END IF;
RAISE INFO 'cmd executed: %', altercmd;
EXECUTE altercmd;
END LOOP;
EXCEPTION WHEN OTHERS THEN RAISE;
END
$$;
-- can only be dropped after views have been rebuilt
DROP FUNCTION IF EXISTS _timescaledb_internal.cagg_watermark(oid);
-- For objects that are newly created, we need to set the initprivs to
-- the initprivs for some table that was created in the installation
-- of the TimescaleDB extension and not as part of any update.
--
-- We chose the "chunk" catalog table for this since that is created
-- in the first version of TimescaleDB and should have the correct
-- initprivs, but we could use any other table that existed in the
-- first installation.
INSERT INTO saved_privs
SELECT nspname, relname, relacl,
(SELECT tmpini FROM saved_privs
WHERE tmpnsp = '_timescaledb_catalog' AND tmpname = 'chunk')
FROM pg_class JOIN pg_namespace ns ON ns.oid = relnamespace
LEFT JOIN saved_privs ON tmpnsp = nspname AND tmpname = relname
WHERE relkind IN ('r', 'v') AND nspname IN ('_timescaledb_catalog', '_timescaledb_config')
OR nspname = '_timescaledb_internal'
AND relname IN ('hypertable_chunk_local_size', 'compressed_chunk_stats',
'bgw_job_stat', 'bgw_policy_chunk_stats')
ON CONFLICT DO NOTHING;
-- The above is good enough for tables and views. However sequences need to
-- use the "chunk_id_seq" catalog sequence as a template
INSERT INTO saved_privs
SELECT nspname, relname, relacl,
(SELECT tmpini FROM saved_privs
WHERE tmpnsp = '_timescaledb_catalog' AND tmpname = 'chunk_id_seq')
FROM pg_class JOIN pg_namespace ns ON ns.oid = relnamespace
LEFT JOIN saved_privs ON tmpnsp = nspname AND tmpname = relname
WHERE relkind IN ('S') AND nspname IN ('_timescaledb_catalog', '_timescaledb_config')
OR nspname = '_timescaledb_internal'
AND relname IN ('hypertable_chunk_local_size', 'compressed_chunk_stats',
'bgw_job_stat', 'bgw_policy_chunk_stats')
ON CONFLICT DO NOTHING;
-- We can now copy back saved initprivs.
WITH to_update AS (
SELECT objoid, tmpini
FROM pg_class cl JOIN pg_namespace ns ON ns.oid = relnamespace
JOIN pg_init_privs ip ON ip.objoid = cl.oid AND ip.objsubid = 0
JOIN saved_privs ON tmpnsp = nspname AND tmpname = relname)
UPDATE pg_init_privs
SET initprivs = tmpini
FROM to_update
WHERE to_update.objoid = pg_init_privs.objoid
AND classoid = 'pg_class'::regclass
AND objsubid = 0;
-- Can only restore permissions on views after they have been rebuilt,
-- so we restore for all types of objects here.
WITH to_update AS (
SELECT cl.oid, tmpacl
FROM pg_class cl JOIN pg_namespace ns ON ns.oid = relnamespace
JOIN saved_privs ON tmpnsp = nspname AND tmpname = relname)
UPDATE pg_class cl SET relacl = tmpacl
FROM to_update WHERE cl.oid = to_update.oid;
DROP TABLE saved_privs;