Use schema-qualified names in EXCEPT clause error messages.

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
This commit is contained in:
Amit Kapila 2026-05-08 10:00:26 +05:30
parent 3f7a1afbae
commit a49b9cfd72
7 changed files with 47 additions and 16 deletions

View 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.")));
}

View 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;

View 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 ---------- */
/*

View 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
* ----------------------------------------------------------------

View 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);

View file

@ -46,6 +46,7 @@ AssertCouldGetRelation(void)
}
#endif
extern Relation RelationIdGetRelation(Oid relationId);
extern char *RelationGetQualifiedRelationName(Relation rel);
extern void RelationClose(Relation relation);
/*

View 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