]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Use schema-qualified names in EXCEPT clause error messages.
authorAmit Kapila <akapila@postgresql.org>
Fri, 8 May 2026 04:30:26 +0000 (10:00 +0530)
committerAmit Kapila <akapila@postgresql.org>
Fri, 8 May 2026 04:30:26 +0000 (10:00 +0530)
Error messages in check_publication_add_relation() previously reported
only the relation name when a table in an EXCEPT clause could not be
processed, which is ambiguous when the same name exists in multiple
schemas. Use schema-qualified names instead, consistent with other error
messages that reference relation names.

Author: Dilip Kumar <dilipbalaut@gmail.com>
Author: vignesh C <vignesh21@gmail.com>
Reviewed-by: shveta malik <shveta.malik@gmail.com>
Reviewed-by: Euler Taveira <euler@eulerto.com>
Reviewed-by: Amit Kapila <amit.kapila16@gmail.com>
Reviewed-by: Peter Smith <smithpb2250@gmail.com>
Discussion: https://postgr.es/m/CAFiTN-scG7b11Jsp+VoDRT8ZFE84eSKLcDsSB18dZ8AaP=R-mw@mail.gmail.com

src/backend/catalog/pg_publication.c
src/backend/utils/adt/ruleutils.c
src/backend/utils/cache/lsyscache.c
src/backend/utils/cache/relcache.c
src/include/utils/lsyscache.h
src/include/utils/relcache.h
src/test/regress/expected/publication.out

index a43d385c60577f00507667062617933aabacada8..5c457d9aca8de93cfda6911b714ecb68d7880ac5 100644 (file)
@@ -56,18 +56,25 @@ static void
 check_publication_add_relation(PublicationRelInfo *pri)
 {
        Relation        targetrel = pri->relation;
+       const char *relname;
        const char *errormsg;
 
        if (pri->except)
+       {
+               relname = RelationGetQualifiedRelationName(targetrel);
                errormsg = gettext_noop("cannot specify relation \"%s\" in the publication EXCEPT clause");
+       }
        else
+       {
+               relname = RelationGetRelationName(targetrel);
                errormsg = gettext_noop("cannot add relation \"%s\" to publication");
+       }
 
        /* If in EXCEPT clause, must be root partitioned table */
        if (pri->except && targetrel->rd_rel->relispartition)
                ereport(ERROR,
                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                                errmsg(errormsg, RelationGetRelationName(targetrel)),
+                                errmsg(errormsg, relname),
                                 errdetail("This operation is not supported for individual partitions.")));
 
        /* Must be a regular or partitioned table */
@@ -75,26 +82,26 @@ check_publication_add_relation(PublicationRelInfo *pri)
                RelationGetForm(targetrel)->relkind != RELKIND_PARTITIONED_TABLE)
                ereport(ERROR,
                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                                errmsg(errormsg, RelationGetRelationName(targetrel)),
+                                errmsg(errormsg, relname),
                                 errdetail_relkind_not_supported(RelationGetForm(targetrel)->relkind)));
 
        /* Can't be system table */
        if (IsCatalogRelation(targetrel))
                ereport(ERROR,
                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                                errmsg(errormsg, RelationGetRelationName(targetrel)),
+                                errmsg(errormsg, relname),
                                 errdetail("This operation is not supported for system tables.")));
 
        /* UNLOGGED and TEMP relations cannot be part of publication. */
        if (targetrel->rd_rel->relpersistence == RELPERSISTENCE_TEMP)
                ereport(ERROR,
                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                                errmsg(errormsg, RelationGetRelationName(targetrel)),
+                                errmsg(errormsg, relname),
                                 errdetail("This operation is not supported for temporary tables.")));
        else if (targetrel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED)
                ereport(ERROR,
                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-                                errmsg(errormsg, RelationGetRelationName(targetrel)),
+                                errmsg(errormsg, relname),
                                 errdetail("This operation is not supported for unlogged tables.")));
 }
 
index 75b77bb39f1ab79b0e7865cf7879796356c8396c..88de5c0481c850b8dfae9e29ce9212bdce697356 100644 (file)
@@ -13876,23 +13876,15 @@ generate_qualified_relation_name(Oid relid)
 {
        HeapTuple       tp;
        Form_pg_class reltup;
-       char       *relname;
-       char       *nspname;
        char       *result;
 
        tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
        if (!HeapTupleIsValid(tp))
                elog(ERROR, "cache lookup failed for relation %u", relid);
        reltup = (Form_pg_class) GETSTRUCT(tp);
-       relname = NameStr(reltup->relname);
-
-       nspname = get_namespace_name_or_temp(reltup->relnamespace);
-       if (!nspname)
-               elog(ERROR, "cache lookup failed for namespace %u",
-                        reltup->relnamespace);
-
-       result = quote_qualified_identifier(nspname, relname);
 
+       result = get_qualified_objname(reltup->relnamespace,
+                                                                  NameStr(reltup->relname));
        ReleaseSysCache(tp);
 
        return result;
index 3de10d4df7e0a48f6522f70c316d98ba3304be5e..036086057d78402bbd839978f190b20413f8d118 100644 (file)
@@ -3628,6 +3628,26 @@ get_namespace_name_or_temp(Oid nspid)
                return get_namespace_name(nspid);
 }
 
+/*
+ * get_qualified_objname
+ *             Returns a palloc'd string containing the schema-qualified name of the
+ *             object for the given namespace ID and object name.
+ */
+char *
+get_qualified_objname(Oid nspid, char *objname)
+{
+       char       *nspname;
+       char       *result;
+
+       nspname = get_namespace_name_or_temp(nspid);
+       if (!nspname)
+               elog(ERROR, "cache lookup failed for namespace %u", nspid);
+
+       result = quote_qualified_identifier(nspname, objname);
+
+       return result;
+}
+
 /*                             ---------- PG_RANGE CACHES ----------                            */
 
 /*
index e19f0d3e51cf33cb99878ad2a7f8d79458851876..0572ab424e71eeaf159ba0f5fd2cb3f3a5de36e3 100644 (file)
@@ -2135,6 +2135,16 @@ 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
  * ----------------------------------------------------------------
index 8d5e92e07be25f54801d91006f7545f59b3fff6f..8545e67a632baeab93ba6d8d3f98752f81af6e8f 100644 (file)
@@ -200,6 +200,7 @@ extern bool get_attstatsslot(AttStatsSlot *sslot, HeapTuple statstuple,
 extern void free_attstatsslot(AttStatsSlot *sslot);
 extern char *get_namespace_name(Oid nspid);
 extern char *get_namespace_name_or_temp(Oid nspid);
+extern char *get_qualified_objname(Oid nspid, char *objname);
 extern Oid     get_range_subtype(Oid rangeOid);
 extern Oid     get_range_collation(Oid rangeOid);
 extern Oid     get_range_constructor2(Oid rangeOid);
index 2700224939a7253edee954314aafb771fe02e12a..89c27aa1529f9356a2b9efbb2d5cec0bdf89875d 100644 (file)
@@ -46,6 +46,7 @@ AssertCouldGetRelation(void)
 }
 #endif
 extern Relation RelationIdGetRelation(Oid relationId);
+extern char *RelationGetQualifiedRelationName(Relation rel);
 extern void RelationClose(Relation relation);
 
 /*
index 0345f6c5e4765e5022114b6d3b2a5303f0810cd2..29e54b214a0a3fa5989515c37b37a5f1938aff2d 100644 (file)
@@ -458,7 +458,7 @@ Excluded from publications:
 Number of partitions: 1 (Use \d+ to list them.)
 
 CREATE PUBLICATION testpub9 FOR ALL TABLES EXCEPT (TABLE testpub_part1);
-ERROR:  cannot specify relation "testpub_part1" in the publication EXCEPT clause
+ERROR:  cannot specify relation "public.testpub_part1" 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