Fix busted Assert for CREATE MATVIEW ... WITH NO DATA.
authorTom Lane
Thu, 11 Aug 2016 15:22:25 +0000 (11:22 -0400)
committerTom Lane
Thu, 11 Aug 2016 15:22:25 +0000 (11:22 -0400)
Commit 874fe3aea changed the command tag returned for CREATE MATVIEW/CREATE
TABLE AS ... WITH NO DATA, but missed that there was code in spi.c that
expected the command tag to always be "SELECT".  Fortunately, the
consequence was only an Assert failure, so this oversight should have no
impact in production builds.

Since this code path was evidently un-exercised, add a regression test.

Per report from Shivam Saxena. Back-patch to 9.3, like the previous commit.

Michael Paquier

Report: <97218716-480B-4527-B5CD-D08D798A0C7B@dresources.com>

src/backend/executor/spi.c
src/test/regress/expected/matview.out
src/test/regress/sql/matview.sql

index dc039f417484a5270bd83b8fd92110264b2eaa54..0eba31d0d0ebd647ee93de3e622deb66597bfa27 100644 (file)
@@ -2224,8 +2224,12 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI,
                            strtoul(completionTag + 7, NULL, 10);
                    else
                    {
-                       /* Must be an IF NOT EXISTS that did nothing */
-                       Assert(ctastmt->if_not_exists);
+                       /*
+                        * Must be an IF NOT EXISTS that did nothing, or a
+                        * CREATE ... WITH NO DATA.
+                        */
+                       Assert(ctastmt->if_not_exists ||
+                              ctastmt->into->skipData);
                        _SPI_current->processed = 0;
                    }
 
index 4ab23700299f870bdd73fc7153e091af525ffbc9..ec11c852ad12b1b2a425488bbaaec1a0a462d61a 100644 (file)
@@ -557,3 +557,28 @@ REFRESH MATERIALIZED VIEW mv_foo;
 REFRESH MATERIALIZED VIEW CONCURRENTLY mv_foo;
 DROP OWNED BY user_dw CASCADE;
 DROP ROLE user_dw;
+-- make sure that create WITH NO DATA works via SPI
+BEGIN;
+CREATE FUNCTION mvtest_func()
+  RETURNS void AS $$
+BEGIN
+  CREATE MATERIALIZED VIEW mvtest1 AS SELECT 1 AS x;
+  CREATE MATERIALIZED VIEW mvtest2 AS SELECT 1 AS x WITH NO DATA;
+END;
+$$ LANGUAGE plpgsql;
+SELECT mvtest_func();
+ mvtest_func 
+-------------
+(1 row)
+
+SELECT * FROM mvtest1;
+ x 
+---
+ 1
+(1 row)
+
+SELECT * FROM mvtest2;
+ERROR:  materialized view "mvtest2" has not been populated
+HINT:  Use the REFRESH MATERIALIZED VIEW command.
+ROLLBACK;
index a37bf5ac5b36d4e88ccff9a535bb2f7771a492c4..8e623cc1ebcceb1f9698b649aeffbc337323bca5 100644 (file)
@@ -226,3 +226,17 @@ REFRESH MATERIALIZED VIEW mv_foo;
 REFRESH MATERIALIZED VIEW CONCURRENTLY mv_foo;
 DROP OWNED BY user_dw CASCADE;
 DROP ROLE user_dw;
+
+-- make sure that create WITH NO DATA works via SPI
+BEGIN;
+CREATE FUNCTION mvtest_func()
+  RETURNS void AS $$
+BEGIN
+  CREATE MATERIALIZED VIEW mvtest1 AS SELECT 1 AS x;
+  CREATE MATERIALIZED VIEW mvtest2 AS SELECT 1 AS x WITH NO DATA;
+END;
+$$ LANGUAGE plpgsql;
+SELECT mvtest_func();
+SELECT * FROM mvtest1;
+SELECT * FROM mvtest2;
+ROLLBACK;