diff --git a/Makefile b/Makefile index c04a546..fcccc3a 100644 --- a/Makefile +++ b/Makefile @@ -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) diff --git a/expected/create_immv.out b/expected/create_immv.out new file mode 100644 index 0000000..a70e96f --- /dev/null +++ b/expected/create_immv.out @@ -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) + diff --git a/pg_ivm--1.0.sql b/pg_ivm--1.0.sql index 3fd9503..7b9c6fd 100644 --- a/pg_ivm--1.0.sql +++ b/pg_ivm--1.0.sql @@ -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(); diff --git a/sql/create_immv.sql b/sql/create_immv.sql new file mode 100644 index 0000000..f5ca551 --- /dev/null +++ b/sql/create_immv.sql @@ -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;