mirror of
https://github.com/postgres/postgres.git
synced 2026-05-16 03:19:53 -04:00
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:
parent
3f7a1afbae
commit
a49b9cfd72
7 changed files with 47 additions and 16 deletions
|
|
@ -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.")));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
20
src/backend/utils/cache/lsyscache.c
vendored
20
src/backend/utils/cache/lsyscache.c
vendored
|
|
@ -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 ---------- */
|
||||
|
||||
/*
|
||||
|
|
|
|||
10
src/backend/utils/cache/relcache.c
vendored
10
src/backend/utils/cache/relcache.c
vendored
|
|
@ -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
|
||||
* ----------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ AssertCouldGetRelation(void)
|
|||
}
|
||||
#endif
|
||||
extern Relation RelationIdGetRelation(Oid relationId);
|
||||
extern char *RelationGetQualifiedRelationName(Relation rel);
|
||||
extern void RelationClose(Relation relation);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue