postgres.git / summary / log / commit / refs

commit    3973034e6dc599de2203ed812f783a57b63dce5c
Author:   Tom Lane <tgl@sss.pgh.pa.us>
Date:     Thu Mar 06 16:37:04 2014 +0000
First released in: 9.4.0, 9.3.4

    Don't reject ROW_MARK_REFERENCE rowmarks for materialized views.
    
    We should allow this so that matviews can be referenced in UPDATE/DELETE
    statements in READ COMMITTED isolation level.  The requirement for that
    is that a re-fetch by TID will see the same row version the query saw
    earlier, which is true of matviews, so there's no reason for the
    restriction.  Per bug #9398.
    
    Michael Paquier, after a suggestion by me


src/backend/executor/execMain.c | 13 +++++++------ src/test/regress/expected/matview.out | 26 ++++++++++++++++++++++++++ src/test/regress/sql/matview.sql | 8 ++++++++ 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 9240b44dc8d..a9c8140581b 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -1100,14 +1100,15 @@ CheckValidRowMarkRel(Relation rel, RowMarkType markType) RelationGetRelationName(rel)))); break; case RELKIND_MATVIEW: - /* Should not get here */ - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("cannot lock rows in materialized view \"%s\"", - RelationGetRelationName(rel)))); + /* Allow referencing a matview, but not actual locking clauses */ + if (markType != ROW_MARK_REFERENCE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot lock rows in materialized view \"%s\"", + RelationGetRelationName(rel)))); break; case RELKIND_FOREIGN_TABLE: - /* Should not get here */ + /* Should not get here; planner should have used ROW_MARK_COPY */ ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("cannot lock rows in foreign table \"%s\"", diff --git a/src/test/regress/expected/matview.out b/src/test/regress/expected/matview.out index c61232fc891..0dc574b75cf 100644 --- a/src/test/regress/expected/matview.out +++ b/src/test/regress/expected/matview.out @@ -412,3 +412,29 @@ SELECT * FROM mv_v; DROP TABLE v CASCADE; NOTICE: drop cascades to materialized view 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; + a +---- + 6 + 7 + 8 + 9 + 10 +(5 rows) + +SELECT * FROM mv_v; + a +--- + 1 + 2 + 3 + 4 + 5 +(5 rows) + +DROP TABLE v CASCADE; +NOTICE: drop cascades to materialized view mv_v diff --git a/src/test/regress/sql/matview.sql b/src/test/regress/sql/matview.sql index 8b1e7349fb2..e9af757d609 100644 --- a/src/test/regress/sql/matview.sql +++ b/src/test/regress/sql/matview.sql @@ -141,3 +141,11 @@ REFRESH MATERIALIZED VIEW mv_v; SELECT * FROM v; SELECT * FROM mv_v; DROP TABLE v CASCADE; + +-- 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; +SELECT * FROM mv_v; +DROP TABLE v CASCADE; [parent: 13ea43ab8387]