Fix CREATE VIEW to allow zero-column views.
authorTom Lane
Sun, 17 Feb 2019 17:37:32 +0000 (12:37 -0500)
committerTom Lane
Sun, 17 Feb 2019 17:37:32 +0000 (12:37 -0500)
We should logically have allowed this case when we allowed zero-column
tables, but it was overlooked.

Although this might be thought a feature addition, it's really a bug
fix, because it was possible to create a zero-column view via
the convert-table-to-view code path, and then you'd have a situation
where dump/reload would fail.  Hence, back-patch to all supported
branches.

Arrange the added test cases to provide coverage of the related
pg_dump code paths (since these views will be dumped and reloaded
during the pg_upgrade regression test).  I also made them test
the case where pg_dump has to postpone the view rule into post-data,
which disturbingly had no regression coverage before.

Report and patch by Ashutosh Sharma (test case by me)

Discussion: https://postgr.es/m/CAE9k0PkmHdeSaeZt2ujnb_cKucmK3sDDceDzw7+d5UZoNJPYOg@mail.gmail.com

src/backend/commands/view.c
src/test/regress/expected/create_view.out
src/test/regress/expected/rules.out
src/test/regress/expected/sanity_check.out
src/test/regress/sql/create_view.sql

index c55f6b0235ab21530a4862f2506907dbb7395a27..615e191f4e7e7a4bc723ff2625d23c098f1da136 100644 (file)
@@ -111,11 +111,6 @@ DefineVirtualRelation(RangeVar *relation, List *tlist, bool replace,
        }
    }
 
-   if (attrList == NIL)
-       ereport(ERROR,
-               (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
-                errmsg("view must have at least one column")));
-
    /*
     * Look up, check permissions on, and lock the creation namespace; also
     * check for a preexisting view with the same name.  This will also set
index f909a3cefeb586737af0e743b70cb877d7c017b9..cfac12492f5a6ac051f099437b5f1c7687a8bcad 100644 (file)
@@ -20,6 +20,16 @@ COMMENT ON VIEW noview IS 'no view';
 ERROR:  relation "noview" does not exist
 COMMENT ON VIEW toyemp IS 'is a view';
 COMMENT ON VIEW toyemp IS NULL;
+-- These views are left around mainly to exercise special cases in pg_dump.
+CREATE TABLE view_base_table (key int PRIMARY KEY, data varchar(20));
+CREATE VIEW key_dependent_view AS
+   SELECT * FROM view_base_table GROUP BY key;
+ALTER TABLE view_base_table DROP CONSTRAINT view_base_table_pkey;  -- fails
+ERROR:  cannot drop constraint view_base_table_pkey on table view_base_table because other objects depend on it
+DETAIL:  view key_dependent_view depends on constraint view_base_table_pkey on table view_base_table
+HINT:  Use DROP ... CASCADE to drop the dependent objects too.
+CREATE VIEW key_dependent_view_no_cols AS
+   SELECT FROM view_base_table GROUP BY key HAVING length(data) > 0;
 --
 -- CREATE OR REPLACE VIEW
 --
index 99e01b9a254852cc7c0fa996448a3acf95a5b0a7..92fd1446d51a8cd818760612dfeb80af24264fe2 100644 (file)
@@ -1289,6 +1289,14 @@ iexit| SELECT ih.name,
    FROM ihighway ih,
     ramp r
   WHERE (ih.thepath ## r.thepath);
+key_dependent_view| SELECT view_base_table.key,
+    view_base_table.data
+   FROM view_base_table
+  GROUP BY view_base_table.key;
+key_dependent_view_no_cols| SELECT
+   FROM view_base_table
+  GROUP BY view_base_table.key
+ HAVING (length((view_base_table.data)::text) > 0);
 mvtest_tv| SELECT mvtest_t.type,
     sum(mvtest_t.amt) AS totamt
    FROM mvtest_t
index 8d2b449f40850a36c96c22b678398363d3940bf1..cebdc978dc24dc7a468b8dafef61d5055345462b 100644 (file)
@@ -189,6 +189,7 @@ timestamp_tbl|f
 timestamptz_tbl|f
 timetz_tbl|f
 varchar_tbl|f
+view_base_table|t
 -- restore normal output mode
 \a\t
 --
index b4e7a8793cb4f0b290b4cf4add691c52a2a6b77e..26bdbec0a426c3973504ce0248f92ddfdc738dfe 100644 (file)
@@ -24,6 +24,18 @@ COMMENT ON VIEW noview IS 'no view';
 COMMENT ON VIEW toyemp IS 'is a view';
 COMMENT ON VIEW toyemp IS NULL;
 
+-- These views are left around mainly to exercise special cases in pg_dump.
+
+CREATE TABLE view_base_table (key int PRIMARY KEY, data varchar(20));
+
+CREATE VIEW key_dependent_view AS
+   SELECT * FROM view_base_table GROUP BY key;
+
+ALTER TABLE view_base_table DROP CONSTRAINT view_base_table_pkey;  -- fails
+
+CREATE VIEW key_dependent_view_no_cols AS
+   SELECT FROM view_base_table GROUP BY key HAVING length(data) > 0;
+
 --
 -- CREATE OR REPLACE VIEW
 --