]> granicus.if.org Git - postgresql/commitdiff
Disallow unlogged materialized views.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 6 May 2013 15:57:05 +0000 (11:57 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 6 May 2013 16:00:06 +0000 (12:00 -0400)
The initial implementation of this feature was really unsupportable,
because it's relying on the physical size of an on-disk file to carry the
relation's populated/unpopulated state, which is at least a modularity
violation and could have serious long-term consequences.  We could say that
an unlogged matview goes to empty on crash, but not everybody likes that
definition, so let's just remove the feature for 9.3.  We can add it back
when we have a less klugy implementation.

I left the grammar and tab-completion support for CREATE UNLOGGED
MATERIALIZED VIEW in place, since it's harmless and allows delivering a
more specific error message about the unsupported feature.

I'm committing this separately to ease identification of what should be
reverted when/if we are able to re-enable the feature.

doc/src/sgml/ref/create_materialized_view.sgml
src/backend/parser/analyze.c
src/test/regress/expected/matview.out
src/test/regress/sql/matview.sql

index a7e4e210eeb0ef20bb7ea046f5c72a36cc4ad880..0ed764b353394137afd73c9a013e031e197ae79c 100644 (file)
@@ -21,7 +21,7 @@ PostgreSQL documentation
 
  <refsynopsisdiv>
 <synopsis>
-CREATE [ UNLOGGED ] MATERIALIZED VIEW <replaceable>table_name</replaceable>
+CREATE MATERIALIZED VIEW <replaceable>table_name</replaceable>
     [ (<replaceable>column_name</replaceable> [, ...] ) ]
     [ WITH ( <replaceable class="PARAMETER">storage_parameter</replaceable> [= <replaceable class="PARAMETER">value</replaceable>] [, ... ] ) ]
     [ TABLESPACE <replaceable class="PARAMETER">tablespace_name</replaceable> ]
@@ -54,16 +54,6 @@ CREATE [ UNLOGGED ] MATERIALIZED VIEW <replaceable>table_name</replaceable>
   <title>Parameters</title>
 
   <variablelist>
-   <varlistentry>
-    <term><literal>UNLOGGED</></term>
-    <listitem>
-     <para>
-      If specified, the materialized view will be unlogged.
-      Refer to <xref linkend="sql-createtable"> for details.
-     </para>
-    </listitem>
-   </varlistentry>
-
    <varlistentry>
     <term><replaceable>table_name</replaceable></term>
     <listitem>
index fb28e471685c7462e8076556a78ef45b561f3d2e..8f8da0523c543d48512c62a7e08534a0cdd91d41 100644 (file)
@@ -2166,6 +2166,18 @@ transformCreateTableAsStmt(ParseState *pstate, CreateTableAsStmt *stmt)
                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                                         errmsg("materialized views may not be defined using bound parameters")));
 
+               /*
+                * For now, we disallow unlogged materialized views, because it
+                * seems like a bad idea for them to just go to empty after a crash.
+                * (If we could mark them as unpopulated, that would be better, but
+                * that requires catalog changes which crash recovery can't presently
+                * handle.)
+                */
+               if (stmt->into->rel->relpersistence == RELPERSISTENCE_UNLOGGED)
+                       ereport(ERROR,
+                                       (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                                        errmsg("materialized views cannot be UNLOGGED")));
+
                /*
                 * At runtime, we'll need a copy of the parsed-but-not-rewritten Query
                 * for purposes of creating the view's ON SELECT rule.  We stash that
index e87775679ac9eb059af776e6e4c20e3bed7360da..06bb2551a83480361ddfce5ad02b76240d9eaf63 100644 (file)
@@ -279,59 +279,8 @@ SELECT * FROM tvvm;
 (1 row)
 
 -- test diemv when the mv does not exist
-DROP MATERIALIZED VIEW IF EXISTS tum;
-NOTICE:  materialized view "tum" does not exist, skipping
--- make sure that an unlogged materialized view works (in the absence of a crash)
-CREATE UNLOGGED MATERIALIZED VIEW tum AS SELECT type, sum(amt) AS totamt FROM t GROUP BY type WITH NO DATA;
-SELECT pg_relation_is_scannable('tum'::regclass);
- pg_relation_is_scannable 
---------------------------
- f
-(1 row)
-
-SELECT * FROM tum;
-ERROR:  materialized view "tum" has not been populated
-HINT:  Use the REFRESH MATERIALIZED VIEW command.
-REFRESH MATERIALIZED VIEW tum;
-SELECT pg_relation_is_scannable('tum'::regclass);
- pg_relation_is_scannable 
---------------------------
- t
-(1 row)
-
-SELECT * FROM tum;
- type | totamt 
-------+--------
- y    |     12
- z    |     24
- x    |      5
-(3 rows)
-
-REFRESH MATERIALIZED VIEW tum WITH NO DATA;
-SELECT pg_relation_is_scannable('tum'::regclass);
- pg_relation_is_scannable 
---------------------------
- f
-(1 row)
-
-SELECT * FROM tum;
-ERROR:  materialized view "tum" has not been populated
-HINT:  Use the REFRESH MATERIALIZED VIEW command.
-REFRESH MATERIALIZED VIEW tum WITH DATA;
-SELECT pg_relation_is_scannable('tum'::regclass);
- pg_relation_is_scannable 
---------------------------
- t
-(1 row)
-
-SELECT * FROM tum;
- type | totamt 
-------+--------
- y    |     12
- z    |     24
- x    |      5
-(3 rows)
-
+DROP MATERIALIZED VIEW IF EXISTS no_such_mv;
+NOTICE:  materialized view "no_such_mv" does not exist, skipping
 -- 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;
  type | mtot | vtot 
@@ -341,8 +290,6 @@ SELECT type, m.totamt AS mtot, v.totamt AS vtot FROM tm m LEFT JOIN tv v USING (
  z    |   24 |   24
 (3 rows)
 
--- test diemv when the mv does exist
-DROP MATERIALIZED VIEW IF EXISTS tum;
 -- 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
index 9fbaafac6d0ae609e80f777754d6f71189cc4af0..09a7378133c86d66755dafd1629719a712badfdf 100644 (file)
@@ -87,28 +87,11 @@ SELECT * FROM tvmm;
 SELECT * FROM tvvm;
 
 -- test diemv when the mv does not exist
-DROP MATERIALIZED VIEW IF EXISTS tum;
-
--- make sure that an unlogged materialized view works (in the absence of a crash)
-CREATE UNLOGGED MATERIALIZED VIEW tum AS SELECT type, sum(amt) AS totamt FROM t GROUP BY type WITH NO DATA;
-SELECT pg_relation_is_scannable('tum'::regclass);
-SELECT * FROM tum;
-REFRESH MATERIALIZED VIEW tum;
-SELECT pg_relation_is_scannable('tum'::regclass);
-SELECT * FROM tum;
-REFRESH MATERIALIZED VIEW tum WITH NO DATA;
-SELECT pg_relation_is_scannable('tum'::regclass);
-SELECT * FROM tum;
-REFRESH MATERIALIZED VIEW tum WITH DATA;
-SELECT pg_relation_is_scannable('tum'::regclass);
-SELECT * FROM tum;
+DROP MATERIALIZED VIEW IF EXISTS no_such_mv;
 
 -- 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;
 
--- test diemv when the mv does exist
-DROP MATERIALIZED VIEW IF EXISTS tum;
-
 -- make sure that dependencies are reported properly when they block the drop
 DROP TABLE t;