From c8aab97c17aaed0133084118a2da99402fd6be14 Mon Sep 17 00:00:00 2001 From: Manu Date: Wed, 16 Sep 2026 09:36:24 -0300 Subject: [PATCH v2] Don't quote the relation name twice in EXCEPT clause errors Commit a49b9cfd72d made check_publication_add_relation() report the relation of an EXCEPT clause with RelationGetQualifiedRelationName(), which quotes identifiers when needed, inside a message that already puts the name in quotes. A name that needs quoting came out quoted twice: ERROR: cannot specify relation "public."testpub Part2"" in the publication EXCEPT clause Build the qualified name without identifier quoting instead, which is the "\"%s.%s\"" form used elsewhere in the backend. The message text, and so its translations, is unchanged. Add a test with such a name. --- src/backend/catalog/pg_publication.c | 8 +++++++- src/backend/utils/cache/relcache.c | 10 ---------- src/include/utils/relcache.h | 1 - src/test/regress/expected/publication.out | 12 +++++++++++- src/test/regress/sql/publication.sql | 8 +++++++- 5 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c index 6b752c4c738..73aa8234f70 100644 --- a/src/backend/catalog/pg_publication.c +++ b/src/backend/catalog/pg_publication.c @@ -62,7 +62,13 @@ check_publication_add_relation(PublicationRelInfo *pri) if (pri->except) { - relname = RelationGetQualifiedRelationName(targetrel); + /* + * The name parts must not be quoted here, because the message already + * encloses the whole name in double quotes. + */ + relname = psprintf("%s.%s", + get_namespace_name_or_temp(RelationGetNamespace(targetrel)), + RelationGetRelationName(targetrel)); errormsg = gettext_noop("cannot specify relation \"%s\" in the publication EXCEPT clause"); } else diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 2555de93706..d8f04a05309 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -2140,16 +2140,6 @@ RelationIdGetRelation(Oid relationId) return rd; } -/* - * Returns a schema-qualified name of the relation. - */ -char * -RelationGetQualifiedRelationName(Relation rel) -{ - return get_qualified_objname(RelationGetNamespace(rel), - RelationGetRelationName(rel)); -} - /* ---------------------------------------------------------------- * cache invalidation support routines * ---------------------------------------------------------------- diff --git a/src/include/utils/relcache.h b/src/include/utils/relcache.h index e17c8490833..3e97da6a538 100644 --- a/src/include/utils/relcache.h +++ b/src/include/utils/relcache.h @@ -46,7 +46,6 @@ AssertCouldGetRelation(void) } #endif extern Relation RelationIdGetRelation(Oid relationId); -extern char *RelationGetQualifiedRelationName(Relation rel); extern void RelationClose(Relation relation); /* diff --git a/src/test/regress/expected/publication.out b/src/test/regress/expected/publication.out index d51b27d7d02..55b3646e2cb 100644 --- a/src/test/regress/expected/publication.out +++ b/src/test/regress/expected/publication.out @@ -514,6 +514,11 @@ Number of partitions: 1 (Use \d+ to list them.) CREATE PUBLICATION testpub9 FOR ALL TABLES EXCEPT (TABLE testpub_part1); ERROR: cannot specify relation "public.testpub_part1" in the publication EXCEPT clause DETAIL: This operation is not supported for individual partitions. +-- A name that needs quoting must not be quoted twice in the message. +CREATE TABLE "testpub Part2" PARTITION OF testpub_root FOR VALUES FROM (100) TO (200); +CREATE PUBLICATION testpub9 FOR ALL TABLES EXCEPT (TABLE "testpub Part2"); +ERROR: cannot specify relation "public.testpub Part2" in the publication EXCEPT clause +DETAIL: This operation is not supported for individual partitions. CREATE TABLE tab_main (a int) PARTITION BY RANGE(a); -- Attaching a partition is not allowed if the partitioned table appears in a -- publication's EXCEPT clause. @@ -522,7 +527,7 @@ ERROR: cannot attach table "testpub_root" as partition because it is referenced DETAIL: The publication EXCEPT clause cannot contain tables that are partitions. HINT: Change the publication's EXCEPT clause using ALTER PUBLICATION ... SET ALL TABLES. RESET client_min_messages; -DROP TABLE testpub_root, testpub_part1, tab_main; +DROP TABLE testpub_root, testpub_part1, "testpub Part2", tab_main; DROP PUBLICATION testpub8; --- Tests for publications with SEQUENCES CREATE SEQUENCE regress_pub_seq0; @@ -1568,6 +1573,11 @@ CREATE TEMPORARY TABLE testpub_temptbl(a int); CREATE PUBLICATION testpub_fortemptbl FOR TABLE testpub_temptbl; ERROR: cannot add relation "testpub_temptbl" to publication DETAIL: This operation is not supported for temporary tables. +-- fail - temporary table in the EXCEPT clause. The schema must be reported +-- as pg_temp. +CREATE PUBLICATION testpub_excepttemptbl FOR ALL TABLES EXCEPT (TABLE testpub_temptbl); +ERROR: cannot specify relation "pg_temp.testpub_temptbl" in the publication EXCEPT clause +DETAIL: This operation is not supported for temporary tables. DROP TABLE testpub_temptbl; CREATE UNLOGGED TABLE testpub_unloggedtbl(a int); -- fail - unlogged table diff --git a/src/test/regress/sql/publication.sql b/src/test/regress/sql/publication.sql index 074482605d9..8ac7216af12 100644 --- a/src/test/regress/sql/publication.sql +++ b/src/test/regress/sql/publication.sql @@ -249,6 +249,9 @@ CREATE PUBLICATION testpub8 FOR ALL TABLES EXCEPT (TABLE testpub_root); \d testpub_part1 \d testpub_root CREATE PUBLICATION testpub9 FOR ALL TABLES EXCEPT (TABLE testpub_part1); +-- A name that needs quoting must not be quoted twice in the message. +CREATE TABLE "testpub Part2" PARTITION OF testpub_root FOR VALUES FROM (100) TO (200); +CREATE PUBLICATION testpub9 FOR ALL TABLES EXCEPT (TABLE "testpub Part2"); CREATE TABLE tab_main (a int) PARTITION BY RANGE(a); -- Attaching a partition is not allowed if the partitioned table appears in a @@ -256,7 +259,7 @@ CREATE TABLE tab_main (a int) PARTITION BY RANGE(a); ALTER TABLE tab_main ATTACH PARTITION testpub_root FOR VALUES FROM (0) TO (200); RESET client_min_messages; -DROP TABLE testpub_root, testpub_part1, tab_main; +DROP TABLE testpub_root, testpub_part1, "testpub Part2", tab_main; DROP PUBLICATION testpub8; --- Tests for publications with SEQUENCES @@ -995,6 +998,9 @@ CREATE PUBLICATION testpub_fortbl FOR TABLE testpub_view; CREATE TEMPORARY TABLE testpub_temptbl(a int); -- fail - temporary table CREATE PUBLICATION testpub_fortemptbl FOR TABLE testpub_temptbl; +-- fail - temporary table in the EXCEPT clause. The schema must be reported +-- as pg_temp. +CREATE PUBLICATION testpub_excepttemptbl FOR ALL TABLES EXCEPT (TABLE testpub_temptbl); DROP TABLE testpub_temptbl; CREATE UNLOGGED TABLE testpub_unloggedtbl(a int); -- 2.54.0