]> granicus.if.org Git - postgresql/commitdiff
Fix CREATE VIEW to allow zero-column views.
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 17 Feb 2019 17:37:32 +0000 (12:37 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
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 67046752d30252580504bb64d39e8a726342743e..ec0c90b42a27f1e84b1b52e1439399d9f934ff18 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 e9a017fecb452551d44cfd440abc7bfa85406f04..1434c2f85aaf1c4f64ad0d10d2553f1506bc6c26 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 1971aa00637a3b7276bfd1477a73a1d95af3777a..eac3ee100ad10b19240b01dfdedd139037b84bb2 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 5eb8b4af9b0e8b521ab3f5819cc80809d4c329f5..4930e6dc72dbd2cb6cbdaa20dec86e78379d7216 100644 (file)
@@ -172,6 +172,7 @@ timestamp_tbl|f
 timestamptz_tbl|f
 timetz_tbl|f
 varchar_tbl|f
+view_base_table|t
 -- restore normal output mode
 \a\t
 --
index 8a365749fce1712b6633affbcc8fd2596f3e5a7e..11f539fcd36c1a09bbde6c21177ca2f3cda2029c 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
 --