]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Don't show tables redundantly when their schema is published.
authorAmit Kapila <akapila@postgresql.org>
Mon, 13 Jul 2026 03:57:47 +0000 (09:27 +0530)
committerAmit Kapila <akapila@postgresql.org>
Mon, 13 Jul 2026 03:57:47 +0000 (09:27 +0530)
A table published both explicitly and through its schema (FOR TABLES IN
SCHEMA) was listed twice by \dRp+ and \d.  Since publishing a schema
publishes its tables in full, the explicit entry's row filter has no
effect; suppress it when the same publication also publishes the table's
schema.

Author: Peter Smith <smithpb2250@gmail.com>
Co-author: Jim Jones <jim.jones@uni-muenster.de>
Reviewed-by: Nisha Moond <nisha.moond412@gmail.com>
Reviewed-by: vignesh C <vignesh21@gmail.com>
Reviewed-by: Shlok Kyal <shlok.kyal.oss@gmail.com>
Discussion: https://postgr.es/m/CAHut%2BPvSOmRrQX%2BVrFYHtFipV9hM%3Dp99FeOwYCzkuU2BOaLu7Q%40mail.gmail.com

src/bin/psql/describe.c
src/test/regress/expected/publication.out
src/test/regress/sql/publication.sql

index fef86b4cca368b9b1bdbf2b46cfa5b6587adf0c2..a2f09c26369900065adcc2e7f89408b687f03c3f 100644 (file)
@@ -3048,7 +3048,17 @@ describeOneTableDetails(const char *schemaname,
                                                          "FROM pg_catalog.pg_publication p\n"
                                                          "     JOIN pg_catalog.pg_publication_rel pr ON p.oid = pr.prpubid\n"
                                                          "     JOIN pg_catalog.pg_class c ON c.oid = pr.prrelid\n"
-                                                         "WHERE pr.prrelid = '%s'\n",
+                                                         "WHERE pr.prrelid = '%s'\n"
+
+                       /*
+                        * Don't print the same publication multiple times when the
+                        * published table is also covered by a published schema.
+                        */
+                                                         "  AND NOT EXISTS (\n"
+                                                         "     SELECT 1\n"
+                                                         "     FROM pg_catalog.pg_publication_namespace pn\n"
+                                                         "     WHERE pn.pnpubid = p.oid\n"
+                                                         "       AND pn.pnnspid = c.relnamespace)\n",
                                                          oid, oid, oid);
 
                        if (pset.sversion >= 190000)
@@ -6793,6 +6803,19 @@ describePublications(const char *pattern)
                                                          "WHERE c.relnamespace = n.oid\n"
                                                          "  AND c.oid = pr.prrelid\n"
                                                          "  AND pr.prpubid = '%s'\n", pubid);
+                       if (pset.sversion >= 150000)
+                       {
+                               /*
+                                * Don't list tables that are also covered by a published
+                                * schema.
+                                */
+                               appendPQExpBuffer(&buf,
+                                                                 "  AND NOT EXISTS (\n"
+                                                                 "     SELECT 1\n"
+                                                                 "     FROM pg_catalog.pg_publication_namespace pn\n"
+                                                                 "     WHERE pn.pnpubid = pr.prpubid\n"
+                                                                 "       AND pn.pnnspid = c.relnamespace)\n");
+                       }
 
                        if (pset.sversion >= 190000)
                                appendPQExpBufferStr(&buf, "  AND NOT pr.prexcept\n");
index 29e54b214a0a3fa5989515c37b37a5f1938aff2d..9c6386d518ac9a9da45428f2fd7ff2e2ea0d84c4 100644 (file)
@@ -146,11 +146,22 @@ RESET client_min_messages;
           Owner           | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Generated columns | Via root | Description 
 --------------------------+------------+---------------+---------+---------+---------+-----------+-------------------+----------+-------------
  regress_publication_user | f          | f             | t       | t       | t       | t         | none              | f        | 
-Tables:
-    "pub_test.testpub_nopk"
 Tables from schemas:
     "pub_test"
 
+-- table also covered by a published schema should appear only once in \d output
+\d pub_test.testpub_nopk
+           Table "pub_test.testpub_nopk"
+ Column |  Type   | Collation | Nullable | Default 
+--------+---------+-----------+----------+---------
+ foo    | integer |           |          | 
+ bar    | integer |           |          | 
+Included in publications:
+    "testpub_for_tbl_schema"
+    "testpub_foralltables"
+    "testpub_forschema"
+    "testpub_fortable"
+
 -- weird parser corner case
 CREATE PUBLICATION testpub_parsertst FOR TABLE pub_test.testpub_nopk, CURRENT_SCHEMA;
 ERROR:  invalid table name
@@ -167,8 +178,6 @@ ALTER PUBLICATION testpub_forschema ADD TABLE pub_test.testpub_nopk;
           Owner           | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Generated columns | Via root | Description 
 --------------------------+------------+---------------+---------+---------+---------+-----------+-------------------+----------+-------------
  regress_publication_user | f          | f             | t       | t       | t       | t         | none              | f        | 
-Tables:
-    "pub_test.testpub_nopk"
 Tables from schemas:
     "pub_test"
 
@@ -832,11 +841,19 @@ RESET client_min_messages;
           Owner           | All tables | All sequences | Inserts | Updates | Deletes | Truncates | Generated columns | Via root | Description 
 --------------------------+------------+---------------+---------+---------+---------+-----------+-------------------+----------+-------------
  regress_publication_user | f          | f             | t       | t       | t       | t         | none              | f        | 
-Tables:
-    "testpub_rf_schema2.testpub_rf_tbl6" WHERE (i < 99)
 Tables from schemas:
     "testpub_rf_schema2"
 
+-- table with a row-filter, also covered by a published schema, should appear
+-- only once in \d output and without the row filter
+\d testpub_rf_schema2.testpub_rf_tbl6
+    Table "testpub_rf_schema2.testpub_rf_tbl6"
+ Column |  Type   | Collation | Nullable | Default 
+--------+---------+-----------+----------+---------
+ i      | integer |           |          | 
+Included in publications:
+    "testpub6"
+
 -- fail - virtual generated column uses user-defined function
 -- (Actually, this already fails at CREATE TABLE rather than at CREATE
 -- PUBLICATION, but let's keep the test in case the former gets
index 041e14a4de697f02f698e291e5217034c695c385..fac54b02e27a3da809ea4725b685f2e29c26104f 100644 (file)
@@ -83,6 +83,8 @@ CREATE PUBLICATION testpub_forschema FOR TABLES IN SCHEMA pub_test;
 CREATE PUBLICATION testpub_for_tbl_schema FOR TABLES IN SCHEMA pub_test, TABLE pub_test.testpub_nopk;
 RESET client_min_messages;
 \dRp+ testpub_for_tbl_schema
+-- table also covered by a published schema should appear only once in \d output
+\d pub_test.testpub_nopk
 
 -- weird parser corner case
 CREATE PUBLICATION testpub_parsertst FOR TABLE pub_test.testpub_nopk, CURRENT_SCHEMA;
@@ -406,6 +408,9 @@ CREATE PUBLICATION testpub6 FOR TABLES IN SCHEMA testpub_rf_schema2;
 ALTER PUBLICATION testpub6 SET TABLES IN SCHEMA testpub_rf_schema2, TABLE testpub_rf_schema2.testpub_rf_tbl6 WHERE (i < 99);
 RESET client_min_messages;
 \dRp+ testpub6
+-- table with a row-filter, also covered by a published schema, should appear
+-- only once in \d output and without the row filter
+\d testpub_rf_schema2.testpub_rf_tbl6
 -- fail - virtual generated column uses user-defined function
 -- (Actually, this already fails at CREATE TABLE rather than at CREATE
 -- PUBLICATION, but let's keep the test in case the former gets