Fix to delete the pg_ivm_immv entry when an IMMV is dropped

This commit is contained in:
Yugo Nagata 2022-04-28 19:47:30 +09:00
parent f68e04524b
commit f2d43bb923
4 changed files with 86 additions and 1 deletions

View file

@ -11,7 +11,7 @@ PGFILEDESC = "pg_ivm - incremental view maintenance on PostgreSQL"
EXTENSION = pg_ivm
DATA = pg_ivm--1.0.sql
REGRESS = pg_ivm
REGRESS = pg_ivm create_immv
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)

43
expected/create_immv.out Normal file
View file

@ -0,0 +1,43 @@
CREATE TABLE t (i int PRIMARY KEY);
INSERT INTO t SELECT generate_series(1, 100);
SELECT create_immv('mv', 'SELECT * FROM t');
NOTICE: created index "mv_index" on immv "mv"
create_immv
-------------
100
(1 row)
SELECT create_immv(' mv2 ( x ) ', 'SELECT * FROM t WHERE i%2 = 0');
NOTICE: created index "mv2_index" on immv "mv2"
create_immv
-------------
50
(1 row)
SELECT create_immv('mv3', 'WITH d AS (DELETE FROM t RETURNING NULL) SELECT * FROM t');
ERROR: materialized views must not use data-modifying statements in WITH
SELECT immvrelid FROM pg_ivm_immv ORDER BY 1;
immvrelid
-----------
mv
mv2
(2 rows)
DROP TABLE t;
ERROR: cannot drop table t because other objects depend on it
DETAIL: table mv depends on table t
table mv2 depends on table t
HINT: Use DROP ... CASCADE to drop the dependent objects too.
DROP TABLE mv;
SELECT immvrelid FROM pg_ivm_immv ORDER BY 1;
immvrelid
-----------
mv2
(1 row)
DROP TABLE mv2;
SELECT immvrelid FROM pg_ivm_immv ORDER BY 1;
immvrelid
-----------
(0 rows)

View file

@ -39,3 +39,28 @@ CREATE FUNCTION "IVM_prevent_immv_change"()
RETURNS trigger
AS 'MODULE_PATHNAME', 'IVM_prevent_immv_change'
LANGUAGE C;
/*
* DDL trigger that removes entry from pg_ivm_immv
*/
CREATE FUNCTION pg_ivm_sql_drop_trigger_func()
RETURNS event_trigger AS $$
DECLARE
pg_class_oid OID;
relids REGCLASS[];
BEGIN
pg_class_oid = 'pg_catalog.pg_class'::regclass;
/* Find relids to remove */
DELETE FROM pg_catalog.pg_ivm_immv
USING pg_catalog.pg_event_trigger_dropped_objects() AS events
WHERE immvrelid = events.objid AND
events.classid = pg_class_oid AND events.objsubid = 0;
END
$$ LANGUAGE plpgsql;
CREATE EVENT TRIGGER pg_ivm_sql_drop_trigger
ON sql_drop
EXECUTE PROCEDURE pg_catalog.pg_ivm_sql_drop_trigger_func();

17
sql/create_immv.sql Normal file
View file

@ -0,0 +1,17 @@
CREATE TABLE t (i int PRIMARY KEY);
INSERT INTO t SELECT generate_series(1, 100);
SELECT create_immv('mv', 'SELECT * FROM t');
SELECT create_immv(' mv2 ( x ) ', 'SELECT * FROM t WHERE i%2 = 0');
SELECT create_immv('mv3', 'WITH d AS (DELETE FROM t RETURNING NULL) SELECT * FROM t');
SELECT immvrelid FROM pg_ivm_immv ORDER BY 1;
DROP TABLE t;
DROP TABLE mv;
SELECT immvrelid FROM pg_ivm_immv ORDER BY 1;
DROP TABLE mv2;
SELECT immvrelid FROM pg_ivm_immv ORDER BY 1;