@ -1,14 +1,14 @@
-- create a table to use as a basis for views and materialized views in various combinations
CREATE TABLE t (id int NOT NULL PRIMARY KEY, type text NOT NULL, amt numeric NOT NULL);
INSERT INTO t VALUES
CREATE TABLE mvtest_ t (id int NOT NULL PRIMARY KEY, type text NOT NULL, amt numeric NOT NULL);
INSERT INTO mvtest_ t VALUES
(1, 'x', 2),
(2, 'x', 3),
(3, 'y', 5),
(4, 'y', 7),
(5, 'z', 11);
-- we want a view based on the table, too, since views present additional challenges
CREATE VIEW tv AS SELECT type, sum(amt) AS totamt FROM t GROUP BY type;
SELECT * FROM tv ORDER BY type;
CREATE VIEW mvtest_ tv AS SELECT type, sum(amt) AS totamt FROM mvtest_ t GROUP BY type;
SELECT * FROM mvtest_ tv ORDER BY type;
type | totamt
------+--------
x | 5
@ -18,33 +18,33 @@ SELECT * FROM tv ORDER BY type;
-- create a materialized view with no data, and confirm correct behavior
EXPLAIN (costs off)
CREATE MATERIALIZED VIEW tm AS SELECT type, sum(amt) AS totamt FROM t GROUP BY type WITH NO DATA;
QUERY PLAN
---------------------
CREATE MATERIALIZED VIEW mvtest_ tm AS SELECT type, sum(amt) AS totamt FROM mvtest_ t GROUP BY type WITH NO DATA;
QUERY PLAN
----------------------------
HashAggregate
Group Key: type
-> Seq Scan on t
-> Seq Scan on mvtest_ t
(3 rows)
CREATE MATERIALIZED VIEW tm AS SELECT type, sum(amt) AS totamt FROM t GROUP BY type WITH NO DATA;
SELECT relispopulated FROM pg_class WHERE oid = 'tm'::regclass;
CREATE MATERIALIZED VIEW mvtest_ tm AS SELECT type, sum(amt) AS totamt FROM mvtest_ t GROUP BY type WITH NO DATA;
SELECT relispopulated FROM pg_class WHERE oid = 'mvtest_ tm'::regclass;
relispopulated
----------------
f
(1 row)
SELECT * FROM tm;
ERROR: materialized view "tm" has not been populated
SELECT * FROM mvtest_ tm;
ERROR: materialized view "mvtest_ tm" has not been populated
HINT: Use the REFRESH MATERIALIZED VIEW command.
REFRESH MATERIALIZED VIEW tm;
SELECT relispopulated FROM pg_class WHERE oid = 'tm'::regclass;
REFRESH MATERIALIZED VIEW mvtest_ tm;
SELECT relispopulated FROM pg_class WHERE oid = 'mvtest_ tm'::regclass;
relispopulated
----------------
t
(1 row)
CREATE UNIQUE INDEX tm_type ON tm (type);
SELECT * FROM tm;
CREATE UNIQUE INDEX mvtest_ tm_type ON mvtest_ tm (type);
SELECT * FROM mvtest_ tm;
type | totamt
------+--------
y | 12
@ -54,18 +54,18 @@ SELECT * FROM tm;
-- create various views
EXPLAIN (costs off)
CREATE MATERIALIZED VIEW tvm AS SELECT * FROM tv ORDER BY type;
QUERY PLAN
---------------------------
CREATE MATERIALIZED VIEW mvtest_ tvm AS SELECT * FROM mvtest_ tv ORDER BY type;
QUERY PLAN
----------------------------------
Sort
Sort Key: t.type
Sort Key: mvtest_ t.type
-> HashAggregate
Group Key: t.type
-> Seq Scan on t
Group Key: mvtest_ t.type
-> Seq Scan on mvtest_ t
(5 rows)
CREATE MATERIALIZED VIEW tvm AS SELECT * FROM tv ORDER BY type;
SELECT * FROM tvm;
CREATE MATERIALIZED VIEW mvtest_ tvm AS SELECT * FROM mvtest_ tv ORDER BY type;
SELECT * FROM mvtest_ tvm;
type | totamt
------+--------
x | 5
@ -73,103 +73,103 @@ SELECT * FROM tvm;
z | 11
(3 rows)
CREATE MATERIALIZED VIEW tmm AS SELECT sum(totamt) AS grandtot FROM tm;
CREATE MATERIALIZED VIEW tvmm AS SELECT sum(totamt) AS grandtot FROM tvm;
CREATE UNIQUE INDEX tvmm_expr ON tvmm ((grandtot > 0));
CREATE UNIQUE INDEX tvmm_pred ON tvmm (grandtot) WHERE grandtot < 0;
CREATE VIEW tvv AS SELECT sum(totamt) AS grandtot FROM tv;
CREATE MATERIALIZED VIEW mvtest_ tmm AS SELECT sum(totamt) AS grandtot FROM mvtest_ tm;
CREATE MATERIALIZED VIEW mvtest_ tvmm AS SELECT sum(totamt) AS grandtot FROM mvtest_ tvm;
CREATE UNIQUE INDEX mvtest_ tvmm_expr ON mvtest_ tvmm ((grandtot > 0));
CREATE UNIQUE INDEX mvtest_ tvmm_pred ON mvtest_ tvmm (grandtot) WHERE grandtot < 0;
CREATE VIEW mvtest_ tvv AS SELECT sum(totamt) AS grandtot FROM mvtest_ tv;
EXPLAIN (costs off)
CREATE MATERIALIZED VIEW tvvm AS SELECT * FROM tvv;
QUERY PLAN
---------------------------
CREATE MATERIALIZED VIEW mvtest_ tvvm AS SELECT * FROM mvtest_ tvv;
QUERY PLAN
----------------------------------
Aggregate
-> HashAggregate
Group Key: t.type
-> Seq Scan on t
Group Key: mvtest_ t.type
-> Seq Scan on mvtest_ t
(4 rows)
CREATE MATERIALIZED VIEW tvvm AS SELECT * FROM tvv;
CREATE VIEW tvvmv AS SELECT * FROM tvvm;
CREATE MATERIALIZED VIEW bb AS SELECT * FROM tvvmv;
CREATE INDEX aa ON bb (grandtot);
CREATE MATERIALIZED VIEW mvtest_ tvvm AS SELECT * FROM mvtest_ tvv;
CREATE VIEW mvtest_ tvvmv AS SELECT * FROM mvtest_ tvvm;
CREATE MATERIALIZED VIEW mvtest_ bb AS SELECT * FROM mvtest_ tvvmv;
CREATE INDEX mvtest_ aa ON mvtest_ bb (grandtot);
-- check that plans seem reasonable
\d+ tvm
Materialized view "public.tvm"
\d+ mvtest_ tvm
Materialized view "public.mvtest_ tvm"
Column | Type | Modifiers | Storage | Stats target | Description
--------+---------+-----------+----------+--------------+-------------
type | text | | extended | |
totamt | numeric | | main | |
View definition:
SELECT tv.type,
tv.totamt
FROM tv
ORDER BY tv.type;
SELECT mvtest_ tv.type,
mvtest_ tv.totamt
FROM mvtest_ tv
ORDER BY mvtest_ tv.type;
\d+ tvm
Materialized view "public.tvm"
\d+ mvtest_ tvm
Materialized view "public.mvtest_ tvm"
Column | Type | Modifiers | Storage | Stats target | Description
--------+---------+-----------+----------+--------------+-------------
type | text | | extended | |
totamt | numeric | | main | |
View definition:
SELECT tv.type,
tv.totamt
FROM tv
ORDER BY tv.type;
SELECT mvtest_ tv.type,
mvtest_ tv.totamt
FROM mvtest_ tv
ORDER BY mvtest_ tv.type;
\d+ tvvm
Materialized view "public.tvvm"
\d+ mvtest_ tvvm
Materialized view "public.mvtest_ tvvm"
Column | Type | Modifiers | Storage | Stats target | Description
----------+---------+-----------+---------+--------------+-------------
grandtot | numeric | | main | |
View definition:
SELECT tvv.grandtot
FROM tvv;
SELECT mvtest_ tvv.grandtot
FROM mvtest_ tvv;
\d+ bb
Materialized view "public.bb"
\d+ mvtest_ bb
Materialized view "public.mvtest_ bb"
Column | Type | Modifiers | Storage | Stats target | Description
----------+---------+-----------+---------+--------------+-------------
grandtot | numeric | | main | |
Indexes:
"aa" btree (grandtot)
"mvtest_ aa" btree (grandtot)
View definition:
SELECT tvvmv.grandtot
FROM tvvmv;
SELECT mvtest_ tvvmv.grandtot
FROM mvtest_ tvvmv;
-- test schema behavior
CREATE SCHEMA mvschema;
ALTER MATERIALIZED VIEW tvm SET SCHEMA mvschema;
\d+ tvm
\d+ tvmm
Materialized view "public.tvmm"
CREATE SCHEMA mvtest_mv schema;
ALTER MATERIALIZED VIEW mvtest_ tvm SET SCHEMA mvtest_ mvschema;
\d+ mvtest_ tvm
\d+ mvtest_ tvmm
Materialized view "public.mvtest_ tvmm"
Column | Type | Modifiers | Storage | Stats target | Description
----------+---------+-----------+---------+--------------+-------------
grandtot | numeric | | main | |
Indexes:
"tvmm_expr" UNIQUE, btree ((grandtot > 0::numeric))
"tvmm_pred" UNIQUE, btree (grandtot) WHERE grandtot < 0::numeric
"mvtest_ tvmm_expr" UNIQUE, btree ((grandtot > 0::numeric))
"mvtest_ tvmm_pred" UNIQUE, btree (grandtot) WHERE grandtot < 0::numeric
View definition:
SELECT sum(tvm.totamt) AS grandtot
FROM mvschema.tvm;
SELECT sum(mvtest_ tvm.totamt) AS grandtot
FROM mvtest_mv schema.mvtest_ tvm;
SET search_path = mvschema, public;
\d+ tvm
Materialized view "mvschema.tvm"
SET search_path = mvtest_mv schema, public;
\d+ mvtest_ tvm
Materialized view "mvtest_mv schema.mvtest_ tvm"
Column | Type | Modifiers | Storage | Stats target | Description
--------+---------+-----------+----------+--------------+-------------
type | text | | extended | |
totamt | numeric | | main | |
View definition:
SELECT tv.type,
tv.totamt
FROM tv
ORDER BY tv.type;
SELECT mvtest_ tv.type,
mvtest_ tv.totamt
FROM mvtest_ tv
ORDER BY mvtest_ tv.type;
-- modify the underlying table data
INSERT INTO t VALUES (6, 'z', 13);
INSERT INTO mvtest_ t VALUES (6, 'z', 13);
-- confirm pre- and post-refresh contents of fairly simple materialized views
SELECT * FROM tm ORDER BY type;
SELECT * FROM mvtest_ tm ORDER BY type;
type | totamt
------+--------
x | 5
@ -177,7 +177,7 @@ SELECT * FROM tm ORDER BY type;
z | 11
(3 rows)
SELECT * FROM tvm ORDER BY type;
SELECT * FROM mvtest_ tvm ORDER BY type;
type | totamt
------+--------
x | 5
@ -185,9 +185,9 @@ SELECT * FROM tvm ORDER BY type;
z | 11
(3 rows)
REFRESH MATERIALIZED VIEW CONCURRENTLY tm;
REFRESH MATERIALIZED VIEW tvm;
SELECT * FROM tm ORDER BY type;
REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_ tm;
REFRESH MATERIALIZED VIEW mvtest_ tvm;
SELECT * FROM mvtest_ tm ORDER BY type;
type | totamt
------+--------
x | 5
@ -195,7 +195,7 @@ SELECT * FROM tm ORDER BY type;
z | 24
(3 rows)
SELECT * FROM tvm ORDER BY type;
SELECT * FROM mvtest_ tvm ORDER BY type;
type | totamt
------+--------
x | 5
@ -206,84 +206,84 @@ SELECT * FROM tvm ORDER BY type;
RESET search_path;
-- confirm pre- and post-refresh contents of nested materialized views
EXPLAIN (costs off)
SELECT * FROM tmm;
QUERY PLAN
-----------------
Seq Scan on tmm
SELECT * FROM mvtest_ tmm;
QUERY PLAN
------------------------
Seq Scan on mvtest_ tmm
(1 row)
EXPLAIN (costs off)
SELECT * FROM tvmm;
QUERY PLAN
------------------
Seq Scan on tvmm
SELECT * FROM mvtest_ tvmm;
QUERY PLAN
-------------------------
Seq Scan on mvtest_ tvmm
(1 row)
EXPLAIN (costs off)
SELECT * FROM tvvm;
QUERY PLAN
------------------
Seq Scan on tvvm
SELECT * FROM mvtest_ tvvm;
QUERY PLAN
-------------------------
Seq Scan on mvtest_ tvvm
(1 row)
SELECT * FROM tmm;
SELECT * FROM mvtest_ tmm;
grandtot
----------
28
(1 row)
SELECT * FROM tvmm;
SELECT * FROM mvtest_ tvmm;
grandtot
----------
28
(1 row)
SELECT * FROM tvvm;
SELECT * FROM mvtest_ tvvm;
grandtot
----------
28
(1 row)
REFRESH MATERIALIZED VIEW tmm;
REFRESH MATERIALIZED VIEW CONCURRENTLY tvmm;
ERROR: cannot refresh materialized view "public.tvmm" concurrently
REFRESH MATERIALIZED VIEW mvtest_ tmm;
REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_ tvmm;
ERROR: cannot refresh materialized view "public.mvtest_ tvmm" concurrently
HINT: Create a unique index with no WHERE clause on one or more columns of the materialized view.
REFRESH MATERIALIZED VIEW tvmm;
REFRESH MATERIALIZED VIEW tvvm;
REFRESH MATERIALIZED VIEW mvtest_ tvmm;
REFRESH MATERIALIZED VIEW mvtest_ tvvm;
EXPLAIN (costs off)
SELECT * FROM tmm;
QUERY PLAN
-----------------
Seq Scan on tmm
SELECT * FROM mvtest_ tmm;
QUERY PLAN
------------------------
Seq Scan on mvtest_ tmm
(1 row)
EXPLAIN (costs off)
SELECT * FROM tvmm;
QUERY PLAN
------------------
Seq Scan on tvmm
SELECT * FROM mvtest_ tvmm;
QUERY PLAN
-------------------------
Seq Scan on mvtest_ tvmm
(1 row)
EXPLAIN (costs off)
SELECT * FROM tvvm;
QUERY PLAN
------------------
Seq Scan on tvvm
SELECT * FROM mvtest_ tvvm;
QUERY PLAN
-------------------------
Seq Scan on mvtest_ tvvm
(1 row)
SELECT * FROM tmm;
SELECT * FROM mvtest_ tmm;
grandtot
----------
41
(1 row)
SELECT * FROM tvmm;
SELECT * FROM mvtest_ tvmm;
grandtot
----------
41
(1 row)
SELECT * FROM tvvm;
SELECT * FROM mvtest_ tvvm;
grandtot
----------
41
@ -293,13 +293,13 @@ SELECT * FROM tvvm;
DROP MATERIALIZED VIEW IF EXISTS no_such_mv;
NOTICE: materialized view "no_such_mv" does not exist, skipping
-- make sure invalid comination of options is prohibited
REFRESH MATERIALIZED VIEW CONCURRENTLY tvmm WITH NO DATA;
REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_ tvmm WITH NO DATA;
ERROR: CONCURRENTLY and WITH NO DATA options cannot be used together
-- no tuple locks on materialized views
SELECT * FROM tvvm FOR SHARE;
ERROR: cannot lock rows in materialized view "tvvm"
SELECT * FROM mvtest_ tvvm FOR SHARE;
ERROR: cannot lock rows in materialized view "mvtest_ tvvm"
-- test join of mv and view
SELECT type, m.totamt AS mtot, v.totamt AS vtot FROM tm m LEFT JOIN tv v USING (type) ORDER BY type;
SELECT type, m.totamt AS mtot, v.totamt AS vtot FROM mvtest_ tm m LEFT JOIN mvtest_ tv v USING (type) ORDER BY type;
type | mtot | vtot
------+------+------
x | 5 | 5
@ -308,53 +308,53 @@ SELECT type, m.totamt AS mtot, v.totamt AS vtot FROM tm m LEFT JOIN tv v USING (
(3 rows)
-- make sure that dependencies are reported properly when they block the drop
DROP TABLE t;
ERROR: cannot drop table t because other objects depend on it
DETAIL: view tv depends on table t
view tvv depends on view tv
materialized view tvvm depends on view tvv
view tvvmv depends on materialized view tvvm
materialized view bb depends on view tvvmv
materialized view mvschema.tvm depends on view tv
materialized view tvmm depends on materialized view mvschema.tvm
materialized view tm depends on table t
materialized view tmm depends on materialized view tm
DROP TABLE mvtest_ t;
ERROR: cannot drop table mvtest_ t because other objects depend on it
DETAIL: view mvtest_ tv depends on table mvtest_ t
view mvtest_ tvv depends on view mvtest_ tv
materialized view mvtest_ tvvm depends on view mvtest_ tvv
view mvtest_ tvvmv depends on materialized view mvtest_ tvvm
materialized view mvtest_ bb depends on view mvtest_ tvvmv
materialized view mvtest_mv schema.mvtest_ tvm depends on view mvtest_ tv
materialized view mvtest_ tvmm depends on materialized view mvtest_mv schema.mvtest_ tvm
materialized view mvtest_ tm depends on table mvtest_ t
materialized view mvtest_ tmm depends on materialized view mvtest_ tm
HINT: Use DROP ... CASCADE to drop the dependent objects too.
-- make sure dependencies are dropped and reported
-- and make sure that transactional behavior is correct on rollback
-- incidentally leaving some interesting materialized views for pg_dump testing
BEGIN;
DROP TABLE t CASCADE;
DROP TABLE mvtest_ t CASCADE;
NOTICE: drop cascades to 9 other objects
DETAIL: drop cascades to view tv
drop cascades to view tvv
drop cascades to materialized view tvvm
drop cascades to view tvvmv
drop cascades to materialized view bb
drop cascades to materialized view mvschema.tvm
drop cascades to materialized view tvmm
drop cascades to materialized view tm
drop cascades to materialized view tmm
DETAIL: drop cascades to view mvtest_ tv
drop cascades to view mvtest_ tvv
drop cascades to materialized view mvtest_ tvvm
drop cascades to view mvtest_ tvvmv
drop cascades to materialized view mvtest_ bb
drop cascades to materialized view mvtest_mv schema.mvtest_ tvm
drop cascades to materialized view mvtest_ tvmm
drop cascades to materialized view mvtest_ tm
drop cascades to materialized view mvtest_ tmm
ROLLBACK;
-- some additional tests not using base tables
CREATE VIEW v_ test1 AS SELECT 1 moo;
CREATE VIEW v_ test2 AS SELECT moo, 2*moo FROM v_ test1 UNION ALL SELECT moo, 3*moo FROM v_ test1;
\d+ v_ test2
View "public.v_ test2"
CREATE VIEW m vtest_v t1 AS SELECT 1 moo;
CREATE VIEW m vtest_v t2 AS SELECT moo, 2*moo FROM m vtest_vt 1 UNION ALL SELECT moo, 3*moo FROM m vtest_v t1;
\d+ m vtest_v t2
View "public.m vtest_v t2"
Column | Type | Modifiers | Storage | Description
----------+---------+-----------+---------+-------------
moo | integer | | plain |
?column? | integer | | plain |
View definition:
SELECT v_ test1.moo,
2 * v_ test1.moo
FROM v_ test1
SELECT m vtest_v t1.moo,
2 * m vtest_v t1.moo
FROM m vtest_v t1
UNION ALL
SELECT v_ test1.moo,
3 * v_ test1.moo
FROM v_ test1;
SELECT m vtest_v t1.moo,
3 * m vtest_v t1.moo
FROM m vtest_v t1;
CREATE MATERIALIZED VIEW mv_test2 AS SELECT moo, 2*moo FROM v_ test2 UNION ALL SELECT moo, 3*moo FROM v_ test2;
CREATE MATERIALIZED VIEW mv_test2 AS SELECT moo, 2*moo FROM m vtest_v t2 UNION ALL SELECT moo, 3*moo FROM m vtest_v t2;
\d+ mv_test2
Materialized view "public.mv_test2"
Column | Type | Modifiers | Storage | Stats target | Description
@ -362,13 +362,13 @@ CREATE MATERIALIZED VIEW mv_test2 AS SELECT moo, 2*moo FROM v_test2 UNION ALL SE
moo | integer | | plain | |
?column? | integer | | plain | |
View definition:
SELECT v_ test2.moo,
2 * v_ test2.moo
FROM v_ test2
SELECT m vtest_v t2.moo,
2 * m vtest_v t2.moo
FROM m vtest_v t2
UNION ALL
SELECT v_ test2.moo,
3 * v_ test2.moo
FROM v_ test2;
SELECT m vtest_v t2.moo,
3 * m vtest_v t2.moo
FROM m vtest_v t2;
CREATE MATERIALIZED VIEW mv_test3 AS SELECT * FROM mv_test2 WHERE moo = 12345;
SELECT relispopulated FROM pg_class WHERE oid = 'mv_test3'::regclass;
@ -377,73 +377,73 @@ SELECT relispopulated FROM pg_class WHERE oid = 'mv_test3'::regclass;
t
(1 row)
DROP VIEW v_ test1 CASCADE;
DROP VIEW m vtest_v t1 CASCADE;
NOTICE: drop cascades to 3 other objects
DETAIL: drop cascades to view v_ test2
DETAIL: drop cascades to view m vtest_v t2
drop cascades to materialized view mv_test2
drop cascades to materialized view mv_test3
-- test that vacuum does not make empty matview look unpopulated
CREATE TABLE ho ge (i int);
INSERT INTO ho ge VALUES (generate_series(1,100000));
CREATE MATERIALIZED VIEW hogeview AS SELECT * FROM ho ge WHERE i % 2 = 0;
CREATE INDEX hogeviewidx ON ho geview (i);
DELETE FROM ho ge;
REFRESH MATERIALIZED VIEW ho geview;
SELECT * FROM ho geview WHERE i < 10;
CREATE TABLE mvtest_hu ge (i int);
INSERT INTO mvtest_hu ge VALUES (generate_series(1,100000));
CREATE MATERIALIZED VIEW mvtest_hugeview AS SELECT * FROM mvtest_hu ge WHERE i % 2 = 0;
CREATE INDEX mvtest_hugeviewidx ON mvtest_hu geview (i);
DELETE FROM mvtest_hu ge;
REFRESH MATERIALIZED VIEW mvtest_hu geview;
SELECT * FROM mvtest_hu geview WHERE i < 10;
i
---
(0 rows)
VACUUM ANALYZE ho geview;
SELECT * FROM ho geview WHERE i < 10;
VACUUM ANALYZE mvtest_hu geview;
SELECT * FROM mvtest_hu geview WHERE i < 10;
i
---
(0 rows)
DROP TABLE ho ge CASCADE;
NOTICE: drop cascades to materialized view ho geview
DROP TABLE mvtest_hu ge CASCADE;
NOTICE: drop cascades to materialized view mvtest_hu geview
-- test that duplicate values on unique index prevent refresh
CREATE TABLE foo(a, b) AS VALUES(1, 10);
CREATE MATERIALIZED VIEW mv AS SELECT * FROM foo;
CREATE UNIQUE INDEX ON mv(a);
INSERT INTO foo SELECT * FROM foo;
REFRESH MATERIALIZED VIEW mv;
ERROR: could not create unique index "mv_a_idx"
CREATE TABLE mvtest_ foo(a, b) AS VALUES(1, 10);
CREATE MATERIALIZED VIEW mvtest_mv AS SELECT * FROM mvtest_ foo;
CREATE UNIQUE INDEX ON mvtest_mv (a);
INSERT INTO mvtest_ foo SELECT * FROM mvtest_ foo;
REFRESH MATERIALIZED VIEW mvtest_mv ;
ERROR: could not create unique index "mvtest_mv _a_idx"
DETAIL: Key (a)=(1) is duplicated.
REFRESH MATERIALIZED VIEW CONCURRENTLY mv;
ERROR: new data for materialized view "mv" contains duplicate rows without any null columns
REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_mv ;
ERROR: new data for materialized view "mvtest_mv " contains duplicate rows without any null columns
DETAIL: Row: (1,10)
DROP TABLE foo CASCADE;
NOTICE: drop cascades to materialized view mv
DROP TABLE mvtest_ foo CASCADE;
NOTICE: drop cascades to materialized view mvtest_mv
-- make sure that all columns covered by unique indexes works
CREATE TABLE foo(a, b, c) AS VALUES(1, 2, 3);
CREATE MATERIALIZED VIEW mv AS SELECT * FROM foo;
CREATE UNIQUE INDEX ON mv (a);
CREATE UNIQUE INDEX ON mv (b);
CREATE UNIQUE INDEX on mv (c);
INSERT INTO foo VALUES(2, 3, 4);
INSERT INTO foo VALUES(3, 4, 5);
REFRESH MATERIALIZED VIEW mv;
REFRESH MATERIALIZED VIEW CONCURRENTLY mv;
DROP TABLE foo CASCADE;
NOTICE: drop cascades to materialized view mv
CREATE TABLE mvtest_ foo(a, b, c) AS VALUES(1, 2, 3);
CREATE MATERIALIZED VIEW mvtest_mv AS SELECT * FROM mvtest_ foo;
CREATE UNIQUE INDEX ON mvtest_mv (a);
CREATE UNIQUE INDEX ON mvtest_mv (b);
CREATE UNIQUE INDEX on mvtest_mv (c);
INSERT INTO mvtest_ foo VALUES(2, 3, 4);
INSERT INTO mvtest_ foo VALUES(3, 4, 5);
REFRESH MATERIALIZED VIEW mvtest_mv ;
REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_mv ;
DROP TABLE mvtest_ foo CASCADE;
NOTICE: drop cascades to materialized view mvtest_mv
-- allow subquery to reference unpopulated matview if WITH NO DATA is specified
CREATE MATERIALIZED VIEW mv1 AS SELECT 1 AS col1 WITH NO DATA;
CREATE MATERIALIZED VIEW mv2 AS SELECT * FROM mv1
WHERE col1 = (SELECT LEAST(col1) FROM mv1) WITH NO DATA;
DROP MATERIALIZED VIEW mv1 CASCADE;
NOTICE: drop cascades to materialized view mv2
CREATE MATERIALIZED VIEW mvtest_mv 1 AS SELECT 1 AS col1 WITH NO DATA;
CREATE MATERIALIZED VIEW mvtest_mv 2 AS SELECT * FROM mvtest_ mv1
WHERE col1 = (SELECT LEAST(col1) FROM mvtest_mv 1) WITH NO DATA;
DROP MATERIALIZED VIEW mvtest_mv 1 CASCADE;
NOTICE: drop cascades to materialized view mvtest_mv 2
-- make sure that types with unusual equality tests work
CREATE TABLE boxes (id serial primary key, b box);
INSERT INTO boxes (b) VALUES
CREATE TABLE mvtest_ boxes (id serial primary key, b box);
INSERT INTO mvtest_ boxes (b) VALUES
('(32,32),(31,31)'),
('(2.0000004,2.0000004),(1,1)'),
('(1.9999996,1.9999996),(1,1)');
CREATE MATERIALIZED VIEW boxmv AS SELECT * FROM boxes;
CREATE UNIQUE INDEX boxmv_id ON boxmv (id);
UPDATE boxes SET b = '(2,2),(1,1)' WHERE id = 2;
REFRESH MATERIALIZED VIEW CONCURRENTLY boxmv;
SELECT * FROM boxmv ORDER BY id;
CREATE MATERIALIZED VIEW mvtest_ boxmv AS SELECT * FROM mvtest_ boxes;
CREATE UNIQUE INDEX mvtest_ boxmv_id ON mvtest_ boxmv (id);
UPDATE mvtest_ boxes SET b = '(2,2),(1,1)' WHERE id = 2;
REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_ boxmv;
SELECT * FROM mvtest_ boxmv ORDER BY id;
id | b
----+-----------------------------
1 | (32,32),(31,31)
@ -451,36 +451,36 @@ SELECT * FROM boxmv ORDER BY id;
3 | (1.9999996,1.9999996),(1,1)
(3 rows)
DROP TABLE boxes CASCADE;
NOTICE: drop cascades to materialized view boxmv
DROP TABLE mvtest_ boxes CASCADE;
NOTICE: drop cascades to materialized view mvtest_ boxmv
-- make sure that column names are handled correctly
CREATE TABLE v (i int, j int);
CREATE MATERIALIZED VIEW mv_v (ii) AS SELECT i, j AS jj FROM v;
ALTER TABLE v RENAME COLUMN i TO x;
INSERT INTO v values (1, 2);
CREATE UNIQUE INDEX mv_v_ii ON mv_v (ii);
REFRESH MATERIALIZED VIEW mv_v;
UPDATE v SET j = 3 WHERE x = 1;
REFRESH MATERIALIZED VIEW CONCURRENTLY mv_v;
SELECT * FROM v;
CREATE TABLE mvtest_ v (i int, j int);
CREATE MATERIALIZED VIEW mvtest_mv _v (ii) AS SELECT i, j AS jj FROM mvtest_ v;
ALTER TABLE mvtest_ v RENAME COLUMN i TO x;
INSERT INTO mvtest_ v values (1, 2);
CREATE UNIQUE INDEX mvtest_mv _v_ii ON mvtest_ mv_v (ii);
REFRESH MATERIALIZED VIEW mvtest_mv _v;
UPDATE mvtest_ v SET j = 3 WHERE x = 1;
REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_mv _v;
SELECT * FROM mvtest_ v;
x | j
---+---
1 | 3
(1 row)
SELECT * FROM mv_v;
SELECT * FROM mvtest_mv _v;
ii | jj
----+----
1 | 3
(1 row)
DROP TABLE v CASCADE;
NOTICE: drop cascades to materialized view mv_v
DROP TABLE mvtest_ v CASCADE;
NOTICE: drop cascades to materialized view mvtest_mv _v
-- make sure that matview rows can be referenced as source rows (bug #9398)
CREATE TABLE v AS SELECT generate_series(1,10) AS a;
CREATE MATERIALIZED VIEW mv_v AS SELECT a FROM v WHERE a <= 5;
DELETE FROM v WHERE EXISTS ( SELECT * FROM mv_v WHERE mv_v.a = v.a );
SELECT * FROM v;
CREATE TABLE mvtest_ v AS SELECT generate_series(1,10) AS a;
CREATE MATERIALIZED VIEW mvtest_mv _v AS SELECT a FROM mvtest_ v WHERE a <= 5;
DELETE FROM mvtest_ v WHERE EXISTS ( SELECT * FROM mvtest_ mv_v WHERE mvtest_mv _v.a = mvtest_ v.a );
SELECT * FROM mvtest_ v;
a
----
6
@ -490,7 +490,7 @@ SELECT * FROM v;
10
(5 rows)
SELECT * FROM mv_v;
SELECT * FROM mvtest_mv _v;
a
---
1
@ -500,21 +500,21 @@ SELECT * FROM mv_v;
5
(5 rows)
DROP TABLE v CASCADE;
NOTICE: drop cascades to materialized view mv_v
DROP TABLE mvtest_ v CASCADE;
NOTICE: drop cascades to materialized view mvtest_mv _v
-- make sure running as superuser works when MV owned by another role (bug #11208)
CREATE ROLE user_dw ;
SET ROLE user_dw ;
CREATE TABLE foo_data AS SELECT i, md5(random()::text)
CREATE ROLE regress_user_mvtest ;
SET ROLE regress_user_mvtest ;
CREATE TABLE mvtest_ foo_data AS SELECT i, md5(random()::text)
FROM generate_series(1, 10) i;
CREATE MATERIALIZED VIEW mv_foo AS SELECT * FROM foo_data;
CREATE MATERIALIZED VIEW mv_foo AS SELECT * FROM foo_data;
ERROR: relation "mv_foo" already exists
CREATE MATERIALIZED VIEW IF NOT EXISTS mv_foo AS SELECT * FROM foo_data;
NOTICE: relation "mv_foo" already exists, skipping
CREATE UNIQUE INDEX ON mv_foo (i);
CREATE MATERIALIZED VIEW mvtest_mv _foo AS SELECT * FROM mvtest_ foo_data;
CREATE MATERIALIZED VIEW mvtest_mv _foo AS SELECT * FROM mvtest_ foo_data;
ERROR: relation "mvtest_mv _foo" already exists
CREATE MATERIALIZED VIEW IF NOT EXISTS mvtest_mv _foo AS SELECT * FROM mvtest_ foo_data;
NOTICE: relation "mvtest_mv _foo" already exists, skipping
CREATE UNIQUE INDEX ON mvtest_mv _foo (i);
RESET ROLE;
REFRESH MATERIALIZED VIEW mv_foo;
REFRESH MATERIALIZED VIEW CONCURRENTLY mv_foo;
DROP OWNED BY user_dw CASCADE;
DROP ROLE user_dw ;
REFRESH MATERIALIZED VIEW mvtest_mv _foo;
REFRESH MATERIALIZED VIEW CONCURRENTLY mvtest_mv _foo;
DROP OWNED BY regress_user_mvtest CASCADE;
DROP ROLE regress_user_mvtest ;