aboutsummaryrefslogtreecommitdiff
path: root/src/backend/catalog/objectaddress.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/catalog/objectaddress.c')
-rw-r--r--src/backend/catalog/objectaddress.c997
1 files changed, 738 insertions, 259 deletions
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index 534df8e8020..6dfe1be2cc0 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -879,14 +879,20 @@ static ObjectAddress get_object_address_defacl(List *object,
bool missing_ok);
static const ObjectPropertyType *get_object_property_data(Oid class_id);
-static void getRelationDescription(StringInfo buffer, Oid relid);
-static void getOpFamilyDescription(StringInfo buffer, Oid opfid);
+static void getRelationDescription(StringInfo buffer, Oid relid,
+ bool missing_ok);
+static void getOpFamilyDescription(StringInfo buffer, Oid opfid,
+ bool missing_ok);
static void getRelationTypeDescription(StringInfo buffer, Oid relid,
- int32 objectSubId);
-static void getProcedureTypeDescription(StringInfo buffer, Oid procid);
-static void getConstraintTypeDescription(StringInfo buffer, Oid constroid);
-static void getOpFamilyIdentity(StringInfo buffer, Oid opfid, List **object);
-static void getRelationIdentity(StringInfo buffer, Oid relid, List **object);
+ int32 objectSubId, bool missing_ok);
+static void getProcedureTypeDescription(StringInfo buffer, Oid procid,
+ bool missing_ok);
+static void getConstraintTypeDescription(StringInfo buffer, Oid constroid,
+ bool missing_ok);
+static void getOpFamilyIdentity(StringInfo buffer, Oid opfid, List **object,
+ bool missing_ok);
+static void getRelationIdentity(StringInfo buffer, Oid relid, List **object,
+ bool missing_ok);
/*
* Translate an object name and arguments (as passed by the parser) to an
@@ -1759,7 +1765,7 @@ get_object_address_opf_member(ObjectType objtype,
membernum,
TypeNameToString(typenames[0]),
TypeNameToString(typenames[1]),
- getObjectDescription(&famaddr))));
+ getObjectDescription(&famaddr, false))));
}
else
{
@@ -1790,7 +1796,7 @@ get_object_address_opf_member(ObjectType objtype,
membernum,
TypeNameToString(typenames[0]),
TypeNameToString(typenames[1]),
- getObjectDescription(&famaddr))));
+ getObjectDescription(&famaddr, false))));
}
else
{
@@ -2844,10 +2850,11 @@ get_catalog_object_by_oid(Relation catalog, AttrNumber oidcol, Oid objectId)
/*
* getObjectDescription: build an object description for messages
*
- * The result is a palloc'd string.
+ * The result is a palloc'd string. NULL is returned for an undefined
+ * object if missing_ok is true, else an error is generated.
*/
char *
-getObjectDescription(const ObjectAddress *object)
+getObjectDescription(const ObjectAddress *object, bool missing_ok)
{
StringInfoData buffer;
@@ -2857,33 +2864,49 @@ getObjectDescription(const ObjectAddress *object)
{
case OCLASS_CLASS:
if (object->objectSubId == 0)
- getRelationDescription(&buffer, object->objectId);
+ getRelationDescription(&buffer, object->objectId, missing_ok);
else
{
/* column, not whole relation */
StringInfoData rel;
+ char *attname = get_attname(object->objectId,
+ object->objectSubId,
+ missing_ok);
+ if (!attname)
+ break;
initStringInfo(&rel);
- getRelationDescription(&rel, object->objectId);
+ getRelationDescription(&rel, object->objectId, missing_ok);
/* translator: second %s is, e.g., "table %s" */
appendStringInfo(&buffer, _("column %s of %s"),
- get_attname(object->objectId,
- object->objectSubId,
- false),
- rel.data);
+ attname, rel.data);
pfree(rel.data);
}
break;
case OCLASS_PROC:
- appendStringInfo(&buffer, _("function %s"),
- format_procedure(object->objectId));
- break;
+ {
+ bits16 flags = FORMAT_PROC_INVALID_AS_NULL;
+ char *proname = format_procedure_extended(object->objectId,
+ flags);
+ if (proname == NULL)
+ break;
+
+ appendStringInfo(&buffer, _("function %s"), proname);
+ break;
+ }
case OCLASS_TYPE:
- appendStringInfo(&buffer, _("type %s"),
- format_type_be(object->objectId));
- break;
+ {
+ bits16 flags = FORMAT_TYPE_INVALID_AS_NULL;
+ char *typname = format_type_extended(object->objectId, -1,
+ flags);
+ if (typname == NULL)
+ break;
+
+ appendStringInfo(&buffer, _("type %s"), typname);
+ break;
+ }
case OCLASS_CAST:
{
@@ -2906,8 +2929,15 @@ getObjectDescription(const ObjectAddress *object)
tup = systable_getnext(rcscan);
if (!HeapTupleIsValid(tup))
- elog(ERROR, "could not find tuple for cast %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "could not find tuple for cast %u",
+ object->objectId);
+
+ systable_endscan(rcscan);
+ table_close(castDesc, AccessShareLock);
+ break;
+ }
castForm = (Form_pg_cast) GETSTRUCT(tup);
@@ -2929,8 +2959,13 @@ getObjectDescription(const ObjectAddress *object)
collTup = SearchSysCache1(COLLOID,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(collTup))
- elog(ERROR, "cache lookup failed for collation %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for collation %u",
+ object->objectId);
+ break;
+ }
+
coll = (Form_pg_collation) GETSTRUCT(collTup);
/* Qualify the name if not visible in search path */
@@ -2954,8 +2989,13 @@ getObjectDescription(const ObjectAddress *object)
conTup = SearchSysCache1(CONSTROID,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(conTup))
- elog(ERROR, "cache lookup failed for constraint %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for constraint %u",
+ object->objectId);
+ break;
+ }
+
con = (Form_pg_constraint) GETSTRUCT(conTup);
if (OidIsValid(con->conrelid))
@@ -2963,7 +3003,7 @@ getObjectDescription(const ObjectAddress *object)
StringInfoData rel;
initStringInfo(&rel);
- getRelationDescription(&rel, con->conrelid);
+ getRelationDescription(&rel, con->conrelid, false);
/* translator: second %s is, e.g., "table %s" */
appendStringInfo(&buffer, _("constraint %s on %s"),
NameStr(con->conname), rel.data);
@@ -2988,8 +3028,13 @@ getObjectDescription(const ObjectAddress *object)
conTup = SearchSysCache1(CONVOID,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(conTup))
- elog(ERROR, "cache lookup failed for conversion %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for conversion %u",
+ object->objectId);
+ break;
+ }
+
conv = (Form_pg_conversion) GETSTRUCT(conTup);
/* Qualify the name if not visible in search path */
@@ -3027,8 +3072,15 @@ getObjectDescription(const ObjectAddress *object)
tup = systable_getnext(adscan);
if (!HeapTupleIsValid(tup))
- elog(ERROR, "could not find tuple for attrdef %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "could not find tuple for attrdef %u",
+ object->objectId);
+
+ systable_endscan(adscan);
+ table_close(attrdefDesc, AccessShareLock);
+ break;
+ }
attrdef = (Form_pg_attrdef) GETSTRUCT(tup);
@@ -3038,7 +3090,7 @@ getObjectDescription(const ObjectAddress *object)
/* translator: %s is typically "column %s of table %s" */
appendStringInfo(&buffer, _("default value for %s"),
- getObjectDescription(&colobject));
+ getObjectDescription(&colobject, false));
systable_endscan(adscan);
table_close(attrdefDesc, AccessShareLock);
@@ -3046,19 +3098,35 @@ getObjectDescription(const ObjectAddress *object)
}
case OCLASS_LANGUAGE:
- appendStringInfo(&buffer, _("language %s"),
- get_language_name(object->objectId, false));
- break;
+ {
+ char *langname = get_language_name(object->objectId,
+ missing_ok);
+
+ if (langname)
+ appendStringInfo(&buffer, _("language %s"),
+ get_language_name(object->objectId, false));
+ break;
+ }
case OCLASS_LARGEOBJECT:
+ if (!LargeObjectExists(object->objectId))
+ break;
appendStringInfo(&buffer, _("large object %u"),
object->objectId);
break;
case OCLASS_OPERATOR:
- appendStringInfo(&buffer, _("operator %s"),
- format_operator(object->objectId));
- break;
+ {
+ bits16 flags = FORMAT_OPERATOR_INVALID_AS_NULL;
+ char *oprname = format_operator_extended(object->objectId,
+ flags);
+
+ if (oprname == NULL)
+ break;
+
+ appendStringInfo(&buffer, _("operator %s"), oprname);
+ break;
+ }
case OCLASS_OPCLASS:
{
@@ -3071,8 +3139,13 @@ getObjectDescription(const ObjectAddress *object)
opcTup = SearchSysCache1(CLAOID,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(opcTup))
- elog(ERROR, "cache lookup failed for opclass %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for opclass %u",
+ object->objectId);
+ break;
+ }
+
opcForm = (Form_pg_opclass) GETSTRUCT(opcTup);
amTup = SearchSysCache1(AMOID,
@@ -3099,7 +3172,7 @@ getObjectDescription(const ObjectAddress *object)
}
case OCLASS_OPFAMILY:
- getOpFamilyDescription(&buffer, object->objectId);
+ getOpFamilyDescription(&buffer, object->objectId, missing_ok);
break;
case OCLASS_AM:
@@ -3109,8 +3182,13 @@ getObjectDescription(const ObjectAddress *object)
tup = SearchSysCache1(AMOID,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(tup))
- elog(ERROR, "cache lookup failed for access method %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for access method %u",
+ object->objectId);
+ break;
+ }
+
appendStringInfo(&buffer, _("access method %s"),
NameStr(((Form_pg_am) GETSTRUCT(tup))->amname));
ReleaseSysCache(tup);
@@ -3140,13 +3218,20 @@ getObjectDescription(const ObjectAddress *object)
tup = systable_getnext(amscan);
if (!HeapTupleIsValid(tup))
- elog(ERROR, "could not find tuple for amop entry %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "could not find tuple for amop entry %u",
+ object->objectId);
+
+ systable_endscan(amscan);
+ table_close(amopDesc, AccessShareLock);
+ break;
+ }
amopForm = (Form_pg_amop) GETSTRUCT(tup);
initStringInfo(&opfam);
- getOpFamilyDescription(&opfam, amopForm->amopfamily);
+ getOpFamilyDescription(&opfam, amopForm->amopfamily, false);
/*------
translator: %d is the operator strategy (a number), the
@@ -3190,13 +3275,20 @@ getObjectDescription(const ObjectAddress *object)
tup = systable_getnext(amscan);
if (!HeapTupleIsValid(tup))
- elog(ERROR, "could not find tuple for amproc entry %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "could not find tuple for amproc entry %u",
+ object->objectId);
+
+ systable_endscan(amscan);
+ table_close(amprocDesc, AccessShareLock);
+ break;
+ }
amprocForm = (Form_pg_amproc) GETSTRUCT(tup);
initStringInfo(&opfam);
- getOpFamilyDescription(&opfam, amprocForm->amprocfamily);
+ getOpFamilyDescription(&opfam, amprocForm->amprocfamily, false);
/*------
translator: %d is the function number, the first two %s's
@@ -3239,12 +3331,20 @@ getObjectDescription(const ObjectAddress *object)
tup = systable_getnext(rcscan);
if (!HeapTupleIsValid(tup))
- elog(ERROR, "could not find tuple for rule %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "could not find tuple for rule %u",
+ object->objectId);
+
+ systable_endscan(rcscan);
+ table_close(ruleDesc, AccessShareLock);
+ break;
+ }
+
rule = (Form_pg_rewrite) GETSTRUCT(tup);
initStringInfo(&rel);
- getRelationDescription(&rel, rule->ev_class);
+ getRelationDescription(&rel, rule->ev_class, false);
/* translator: second %s is, e.g., "table %s" */
appendStringInfo(&buffer, _("rule %s on %s"),
@@ -3277,12 +3377,20 @@ getObjectDescription(const ObjectAddress *object)
tup = systable_getnext(tgscan);
if (!HeapTupleIsValid(tup))
- elog(ERROR, "could not find tuple for trigger %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "could not find tuple for trigger %u",
+ object->objectId);
+
+ systable_endscan(tgscan);
+ table_close(trigDesc, AccessShareLock);
+ break;
+ }
+
trig = (Form_pg_trigger) GETSTRUCT(tup);
initStringInfo(&rel);
- getRelationDescription(&rel, trig->tgrelid);
+ getRelationDescription(&rel, trig->tgrelid, false);
/* translator: second %s is, e.g., "table %s" */
appendStringInfo(&buffer, _("trigger %s on %s"),
@@ -3299,8 +3407,12 @@ getObjectDescription(const ObjectAddress *object)
nspname = get_namespace_name(object->objectId);
if (!nspname)
- elog(ERROR, "cache lookup failed for namespace %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for namespace %u",
+ object->objectId);
+ break;
+ }
appendStringInfo(&buffer, _("schema %s"), nspname);
break;
}
@@ -3314,8 +3426,13 @@ getObjectDescription(const ObjectAddress *object)
stxTup = SearchSysCache1(STATEXTOID,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(stxTup))
- elog(ERROR, "could not find tuple for statistics object %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "could not find tuple for statistics object %u",
+ object->objectId);
+ break;
+ }
+
stxForm = (Form_pg_statistic_ext) GETSTRUCT(stxTup);
/* Qualify the name if not visible in search path */
@@ -3341,8 +3458,12 @@ getObjectDescription(const ObjectAddress *object)
tup = SearchSysCache1(TSPARSEROID,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(tup))
- elog(ERROR, "cache lookup failed for text search parser %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for text search parser %u",
+ object->objectId);
+ break;
+ }
prsForm = (Form_pg_ts_parser) GETSTRUCT(tup);
/* Qualify the name if not visible in search path */
@@ -3367,8 +3488,13 @@ getObjectDescription(const ObjectAddress *object)
tup = SearchSysCache1(TSDICTOID,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(tup))
- elog(ERROR, "cache lookup failed for text search dictionary %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for text search dictionary %u",
+ object->objectId);
+ break;
+ }
+
dictForm = (Form_pg_ts_dict) GETSTRUCT(tup);
/* Qualify the name if not visible in search path */
@@ -3393,8 +3519,13 @@ getObjectDescription(const ObjectAddress *object)
tup = SearchSysCache1(TSTEMPLATEOID,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(tup))
- elog(ERROR, "cache lookup failed for text search template %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for text search template %u",
+ object->objectId);
+ break;
+ }
+
tmplForm = (Form_pg_ts_template) GETSTRUCT(tup);
/* Qualify the name if not visible in search path */
@@ -3419,8 +3550,13 @@ getObjectDescription(const ObjectAddress *object)
tup = SearchSysCache1(TSCONFIGOID,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(tup))
- elog(ERROR, "cache lookup failed for text search configuration %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for text search configuration %u",
+ object->objectId);
+ break;
+ }
+
cfgForm = (Form_pg_ts_config) GETSTRUCT(tup);
/* Qualify the name if not visible in search path */
@@ -3438,8 +3574,11 @@ getObjectDescription(const ObjectAddress *object)
case OCLASS_ROLE:
{
- appendStringInfo(&buffer, _("role %s"),
- GetUserNameFromId(object->objectId, false));
+ char *username = GetUserNameFromId(object->objectId,
+ missing_ok);
+
+ if (username)
+ appendStringInfo(&buffer, _("role %s"), username);
break;
}
@@ -3449,8 +3588,12 @@ getObjectDescription(const ObjectAddress *object)
datname = get_database_name(object->objectId);
if (!datname)
- elog(ERROR, "cache lookup failed for database %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for database %u",
+ object->objectId);
+ break;
+ }
appendStringInfo(&buffer, _("database %s"), datname);
break;
}
@@ -3461,8 +3604,12 @@ getObjectDescription(const ObjectAddress *object)
tblspace = get_tablespace_name(object->objectId);
if (!tblspace)
- elog(ERROR, "cache lookup failed for tablespace %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for tablespace %u",
+ object->objectId);
+ break;
+ }
appendStringInfo(&buffer, _("tablespace %s"), tblspace);
break;
}
@@ -3471,8 +3618,10 @@ getObjectDescription(const ObjectAddress *object)
{
ForeignDataWrapper *fdw;
- fdw = GetForeignDataWrapper(object->objectId);
- appendStringInfo(&buffer, _("foreign-data wrapper %s"), fdw->fdwname);
+ fdw = GetForeignDataWrapperExtended(object->objectId,
+ missing_ok);
+ if (fdw)
+ appendStringInfo(&buffer, _("foreign-data wrapper %s"), fdw->fdwname);
break;
}
@@ -3480,8 +3629,9 @@ getObjectDescription(const ObjectAddress *object)
{
ForeignServer *srv;
- srv = GetForeignServer(object->objectId);
- appendStringInfo(&buffer, _("server %s"), srv->servername);
+ srv = GetForeignServerExtended(object->objectId, missing_ok);
+ if (srv)
+ appendStringInfo(&buffer, _("server %s"), srv->servername);
break;
}
@@ -3496,8 +3646,13 @@ getObjectDescription(const ObjectAddress *object)
tup = SearchSysCache1(USERMAPPINGOID,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(tup))
- elog(ERROR, "cache lookup failed for user mapping %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for user mapping %u",
+ object->objectId);
+ break;
+ }
+
umform = (Form_pg_user_mapping) GETSTRUCT(tup);
useid = umform->umuser;
srv = GetForeignServer(umform->umserver);
@@ -3537,8 +3692,15 @@ getObjectDescription(const ObjectAddress *object)
tup = systable_getnext(rcscan);
if (!HeapTupleIsValid(tup))
- elog(ERROR, "could not find tuple for default ACL %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "could not find tuple for default ACL %u",
+ object->objectId);
+
+ systable_endscan(rcscan);
+ table_close(defaclrel, AccessShareLock);
+ break;
+ }
defacl = (Form_pg_default_acl) GETSTRUCT(tup);
@@ -3621,8 +3783,12 @@ getObjectDescription(const ObjectAddress *object)
extname = get_extension_name(object->objectId);
if (!extname)
- elog(ERROR, "cache lookup failed for extension %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for extension %u",
+ object->objectId);
+ break;
+ }
appendStringInfo(&buffer, _("extension %s"), extname);
break;
}
@@ -3634,8 +3800,12 @@ getObjectDescription(const ObjectAddress *object)
tup = SearchSysCache1(EVENTTRIGGEROID,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(tup))
- elog(ERROR, "cache lookup failed for event trigger %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for event trigger %u",
+ object->objectId);
+ break;
+ }
appendStringInfo(&buffer, _("event trigger %s"),
NameStr(((Form_pg_event_trigger) GETSTRUCT(tup))->evtname));
ReleaseSysCache(tup);
@@ -3664,12 +3834,20 @@ getObjectDescription(const ObjectAddress *object)
tuple = systable_getnext(sscan);
if (!HeapTupleIsValid(tuple))
- elog(ERROR, "could not find tuple for policy %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "could not find tuple for policy %u",
+ object->objectId);
+
+ systable_endscan(sscan);
+ table_close(policy_rel, AccessShareLock);
+ break;
+ }
+
form_policy = (Form_pg_policy) GETSTRUCT(tuple);
initStringInfo(&rel);
- getRelationDescription(&rel, form_policy->polrelid);
+ getRelationDescription(&rel, form_policy->polrelid, false);
/* translator: second %s is, e.g., "table %s" */
appendStringInfo(&buffer, _("policy %s on %s"),
@@ -3682,9 +3860,10 @@ getObjectDescription(const ObjectAddress *object)
case OCLASS_PUBLICATION:
{
- appendStringInfo(&buffer, _("publication %s"),
- get_publication_name(object->objectId,
- false));
+ char *pubname = get_publication_name(object->objectId,
+ missing_ok);
+ if (pubname)
+ appendStringInfo(&buffer, _("publication %s"), pubname);
break;
}
@@ -3698,14 +3877,18 @@ getObjectDescription(const ObjectAddress *object)
tup = SearchSysCache1(PUBLICATIONREL,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(tup))
- elog(ERROR, "cache lookup failed for publication table %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for publication table %u",
+ object->objectId);
+ break;
+ }
prform = (Form_pg_publication_rel) GETSTRUCT(tup);
pubname = get_publication_name(prform->prpubid, false);
initStringInfo(&rel);
- getRelationDescription(&rel, prform->prrelid);
+ getRelationDescription(&rel, prform->prrelid, false);
/* translator: first %s is, e.g., "table %s" */
appendStringInfo(&buffer, _("publication of %s in publication %s"),
@@ -3717,9 +3900,10 @@ getObjectDescription(const ObjectAddress *object)
case OCLASS_SUBSCRIPTION:
{
- appendStringInfo(&buffer, _("subscription %s"),
- get_subscription_name(object->objectId,
- false));
+ char *subname = get_subscription_name(object->objectId,
+ missing_ok);
+ if (subname)
+ appendStringInfo(&buffer, _("subscription %s"), subname);
break;
}
@@ -3731,8 +3915,12 @@ getObjectDescription(const ObjectAddress *object)
trfTup = SearchSysCache1(TRFOID,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(trfTup))
- elog(ERROR, "could not find tuple for transform %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "could not find tuple for transform %u",
+ object->objectId);
+ break;
+ }
trfForm = (Form_pg_transform) GETSTRUCT(trfTup);
@@ -3750,6 +3938,10 @@ getObjectDescription(const ObjectAddress *object)
*/
}
+ /* an empty buffer is equivalent to no object found */
+ if (buffer.len == 0)
+ return NULL;
+
return buffer.data;
}
@@ -3765,7 +3957,7 @@ getObjectDescriptionOids(Oid classid, Oid objid)
address.objectId = objid;
address.objectSubId = 0;
- return getObjectDescription(&address);
+ return getObjectDescription(&address, false);
}
/*
@@ -3774,7 +3966,7 @@ getObjectDescriptionOids(Oid classid, Oid objid)
* The result is appended to "buffer".
*/
static void
-getRelationDescription(StringInfo buffer, Oid relid)
+getRelationDescription(StringInfo buffer, Oid relid, bool missing_ok)
{
HeapTuple relTup;
Form_pg_class relForm;
@@ -3784,7 +3976,11 @@ getRelationDescription(StringInfo buffer, Oid relid)
relTup = SearchSysCache1(RELOID,
ObjectIdGetDatum(relid));
if (!HeapTupleIsValid(relTup))
- elog(ERROR, "cache lookup failed for relation %u", relid);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for relation %u", relid);
+ return;
+ }
relForm = (Form_pg_class) GETSTRUCT(relTup);
/* Qualify the name if not visible in search path */
@@ -3845,7 +4041,7 @@ getRelationDescription(StringInfo buffer, Oid relid)
* subroutine for getObjectDescription: describe an operator family
*/
static void
-getOpFamilyDescription(StringInfo buffer, Oid opfid)
+getOpFamilyDescription(StringInfo buffer, Oid opfid, bool missing_ok)
{
HeapTuple opfTup;
Form_pg_opfamily opfForm;
@@ -3855,7 +4051,11 @@ getOpFamilyDescription(StringInfo buffer, Oid opfid)
opfTup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfid));
if (!HeapTupleIsValid(opfTup))
- elog(ERROR, "cache lookup failed for opfamily %u", opfid);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for opfamily %u", opfid);
+ return;
+ }
opfForm = (Form_pg_opfamily) GETSTRUCT(opfTup);
amTup = SearchSysCache1(AMOID, ObjectIdGetDatum(opfForm->opfmethod));
@@ -3899,7 +4099,11 @@ pg_describe_object(PG_FUNCTION_ARGS)
address.objectId = objid;
address.objectSubId = objsubid;
- description = getObjectDescription(&address);
+ description = getObjectDescription(&address, true);
+
+ if (description == NULL)
+ PG_RETURN_NULL();
+
PG_RETURN_TEXT_P(cstring_to_text(description));
}
@@ -3914,6 +4118,7 @@ pg_identify_object(PG_FUNCTION_ARGS)
int32 objsubid = PG_GETARG_INT32(2);
Oid schema_oid = InvalidOid;
const char *objname = NULL;
+ char *objidentity;
ObjectAddress address;
Datum values[4];
bool nulls[4];
@@ -3988,12 +4193,18 @@ pg_identify_object(PG_FUNCTION_ARGS)
table_close(catalog, AccessShareLock);
}
- /* object type */
- values[0] = CStringGetTextDatum(getObjectTypeDescription(&address));
+ /* object type, which can never be NULL */
+ values[0] = CStringGetTextDatum(getObjectTypeDescription(&address, true));
nulls[0] = false;
+ /*
+ * Before doing anything, extract the object identity. If the identity
+ * could not be found, set all the fields except the object type to NULL.
+ */
+ objidentity = getObjectIdentity(&address, true);
+
/* schema name */
- if (OidIsValid(schema_oid))
+ if (OidIsValid(schema_oid) && objidentity)
{
const char *schema = quote_identifier(get_namespace_name(schema_oid));
@@ -4004,7 +4215,7 @@ pg_identify_object(PG_FUNCTION_ARGS)
nulls[1] = true;
/* object name */
- if (objname)
+ if (objname && objidentity)
{
values[2] = CStringGetTextDatum(objname);
nulls[2] = false;
@@ -4013,8 +4224,13 @@ pg_identify_object(PG_FUNCTION_ARGS)
nulls[2] = true;
/* object identity */
- values[3] = CStringGetTextDatum(getObjectIdentity(&address));
- nulls[3] = false;
+ if (objidentity)
+ {
+ values[3] = CStringGetTextDatum(objidentity);
+ nulls[3] = false;
+ }
+ else
+ nulls[3] = true;
htup = heap_form_tuple(tupdesc, values, nulls);
@@ -4058,26 +4274,34 @@ pg_identify_object_as_address(PG_FUNCTION_ARGS)
tupdesc = BlessTupleDesc(tupdesc);
/* object type */
- values[0] = CStringGetTextDatum(getObjectTypeDescription(&address));
+ values[0] = CStringGetTextDatum(getObjectTypeDescription(&address, true));
nulls[0] = false;
/* object identity */
- identity = getObjectIdentityParts(&address, &names, &args);
- pfree(identity);
-
- /* object_names */
- if (names != NIL)
- values[1] = PointerGetDatum(strlist_to_textarray(names));
+ identity = getObjectIdentityParts(&address, &names, &args, true);
+ if (identity == NULL)
+ {
+ nulls[1] = true;
+ nulls[2] = true;
+ }
else
- values[1] = PointerGetDatum(construct_empty_array(TEXTOID));
- nulls[1] = false;
+ {
+ pfree(identity);
- /* object_args */
- if (args)
- values[2] = PointerGetDatum(strlist_to_textarray(args));
- else
- values[2] = PointerGetDatum(construct_empty_array(TEXTOID));
- nulls[2] = false;
+ /* object_names */
+ if (names != NIL)
+ values[1] = PointerGetDatum(strlist_to_textarray(names));
+ else
+ values[1] = PointerGetDatum(construct_empty_array(TEXTOID));
+ nulls[1] = false;
+
+ /* object_args */
+ if (args)
+ values[2] = PointerGetDatum(strlist_to_textarray(args));
+ else
+ values[2] = PointerGetDatum(construct_empty_array(TEXTOID));
+ nulls[2] = false;
+ }
htup = heap_form_tuple(tupdesc, values, nulls);
@@ -4091,7 +4315,7 @@ pg_identify_object_as_address(PG_FUNCTION_ARGS)
* Keep ObjectTypeMap in sync with this.
*/
char *
-getObjectTypeDescription(const ObjectAddress *object)
+getObjectTypeDescription(const ObjectAddress *object, bool missing_ok)
{
StringInfoData buffer;
@@ -4101,11 +4325,13 @@ getObjectTypeDescription(const ObjectAddress *object)
{
case OCLASS_CLASS:
getRelationTypeDescription(&buffer, object->objectId,
- object->objectSubId);
+ object->objectSubId,
+ missing_ok);
break;
case OCLASS_PROC:
- getProcedureTypeDescription(&buffer, object->objectId);
+ getProcedureTypeDescription(&buffer, object->objectId,
+ missing_ok);
break;
case OCLASS_TYPE:
@@ -4121,7 +4347,8 @@ getObjectTypeDescription(const ObjectAddress *object)
break;
case OCLASS_CONSTRAINT:
- getConstraintTypeDescription(&buffer, object->objectId);
+ getConstraintTypeDescription(&buffer, object->objectId,
+ missing_ok);
break;
case OCLASS_CONVERSION:
@@ -4258,6 +4485,10 @@ getObjectTypeDescription(const ObjectAddress *object)
*/
}
+ /* an empty string is equivalent to no object found */
+ if (buffer.len == 0)
+ return NULL;
+
return buffer.data;
}
@@ -4265,7 +4496,8 @@ getObjectTypeDescription(const ObjectAddress *object)
* subroutine for getObjectTypeDescription: describe a relation type
*/
static void
-getRelationTypeDescription(StringInfo buffer, Oid relid, int32 objectSubId)
+getRelationTypeDescription(StringInfo buffer, Oid relid, int32 objectSubId,
+ bool missing_ok)
{
HeapTuple relTup;
Form_pg_class relForm;
@@ -4273,7 +4505,14 @@ getRelationTypeDescription(StringInfo buffer, Oid relid, int32 objectSubId)
relTup = SearchSysCache1(RELOID,
ObjectIdGetDatum(relid));
if (!HeapTupleIsValid(relTup))
- elog(ERROR, "cache lookup failed for relation %u", relid);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for relation %u", relid);
+
+ /* fallback to "relation" for an undefined object */
+ appendStringInfoString(buffer, "relation");
+ return;
+ }
relForm = (Form_pg_class) GETSTRUCT(relTup);
switch (relForm->relkind)
@@ -4320,7 +4559,7 @@ getRelationTypeDescription(StringInfo buffer, Oid relid, int32 objectSubId)
* subroutine for getObjectTypeDescription: describe a constraint type
*/
static void
-getConstraintTypeDescription(StringInfo buffer, Oid constroid)
+getConstraintTypeDescription(StringInfo buffer, Oid constroid, bool missing_ok)
{
Relation constrRel;
HeapTuple constrTup;
@@ -4330,7 +4569,16 @@ getConstraintTypeDescription(StringInfo buffer, Oid constroid)
constrTup = get_catalog_object_by_oid(constrRel, Anum_pg_constraint_oid,
constroid);
if (!HeapTupleIsValid(constrTup))
- elog(ERROR, "cache lookup failed for constraint %u", constroid);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for constraint %u", constroid);
+
+ table_close(constrRel, AccessShareLock);
+
+ /* fallback to "constraint" for an undefined object */
+ appendStringInfoString(buffer, "constraint");
+ return;
+ }
constrForm = (Form_pg_constraint) GETSTRUCT(constrTup);
@@ -4348,7 +4596,8 @@ getConstraintTypeDescription(StringInfo buffer, Oid constroid)
* subroutine for getObjectTypeDescription: describe a procedure type
*/
static void
-getProcedureTypeDescription(StringInfo buffer, Oid procid)
+getProcedureTypeDescription(StringInfo buffer, Oid procid,
+ bool missing_ok)
{
HeapTuple procTup;
Form_pg_proc procForm;
@@ -4356,7 +4605,14 @@ getProcedureTypeDescription(StringInfo buffer, Oid procid)
procTup = SearchSysCache1(PROCOID,
ObjectIdGetDatum(procid));
if (!HeapTupleIsValid(procTup))
- elog(ERROR, "cache lookup failed for procedure %u", procid);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for procedure %u", procid);
+
+ /* fallback to "procedure" for an undefined object */
+ appendStringInfoString(buffer, "routine");
+ return;
+ }
procForm = (Form_pg_proc) GETSTRUCT(procTup);
if (procForm->prokind == PROKIND_AGGREGATE)
@@ -4373,12 +4629,13 @@ getProcedureTypeDescription(StringInfo buffer, Oid procid)
* Obtain a given object's identity, as a palloc'ed string.
*
* This is for machine consumption, so it's not translated. All elements are
- * schema-qualified when appropriate.
+ * schema-qualified when appropriate. Returns NULL if the object could not
+ * be found.
*/
char *
-getObjectIdentity(const ObjectAddress *object)
+getObjectIdentity(const ObjectAddress *object, bool missing_ok)
{
- return getObjectIdentityParts(object, NULL, NULL);
+ return getObjectIdentityParts(object, NULL, NULL, missing_ok);
}
/*
@@ -4387,11 +4644,13 @@ getObjectIdentity(const ObjectAddress *object)
* There are two sets of return values: the identity itself as a palloc'd
* string is returned. objname and objargs, if not NULL, are output parameters
* that receive lists of C-strings that are useful to give back to
- * get_object_address() to reconstruct the ObjectAddress.
+ * get_object_address() to reconstruct the ObjectAddress. Returns NULL if
+ * the object could not be found.
*/
char *
getObjectIdentityParts(const ObjectAddress *object,
- List **objname, List **objargs)
+ List **objname, List **objargs,
+ bool missing_ok)
{
StringInfoData buffer;
@@ -4413,31 +4672,63 @@ getObjectIdentityParts(const ObjectAddress *object,
switch (getObjectClass(object))
{
case OCLASS_CLASS:
- getRelationIdentity(&buffer, object->objectId, objname);
- if (object->objectSubId != 0)
{
- char *attr;
+ char *attr = NULL;
- attr = get_attname(object->objectId, object->objectSubId,
- false);
- appendStringInfo(&buffer, ".%s", quote_identifier(attr));
- if (objname)
- *objname = lappend(*objname, attr);
+ /*
+ * Check for the attribute first, so as if it is missing we
+ * can skip the entire relation description.
+ */
+ if (object->objectSubId != 0)
+ {
+ attr = get_attname(object->objectId,
+ object->objectSubId,
+ missing_ok);
+
+ if (missing_ok && attr == NULL)
+ break;
+ }
+
+ getRelationIdentity(&buffer, object->objectId, objname,
+ missing_ok);
+ if (objname && *objname == NIL)
+ break;
+
+ if (attr)
+ {
+ appendStringInfo(&buffer, ".%s",
+ quote_identifier(attr));
+ if (objname)
+ *objname = lappend(*objname, attr);
+ }
}
break;
case OCLASS_PROC:
- appendStringInfoString(&buffer,
- format_procedure_qualified(object->objectId));
- if (objname)
- format_procedure_parts(object->objectId, objname, objargs);
- break;
+ {
+ bits16 flags = FORMAT_PROC_FORCE_QUALIFY | FORMAT_PROC_INVALID_AS_NULL;
+ char *proname = format_procedure_extended(object->objectId,
+ flags);
+ if (proname == NULL)
+ break;
+
+ appendStringInfoString(&buffer, proname);
+ if (objname)
+ format_procedure_parts(object->objectId, objname, objargs,
+ missing_ok);
+ break;
+ }
case OCLASS_TYPE:
{
+ bits16 flags = FORMAT_TYPE_INVALID_AS_NULL | FORMAT_TYPE_FORCE_QUALIFY;
char *typeout;
- typeout = format_type_be_qualified(object->objectId);
+ typeout = format_type_extended(object->objectId, -1, flags);
+
+ if (typeout == NULL)
+ break;
+
appendStringInfoString(&buffer, typeout);
if (objname)
*objname = list_make1(typeout);
@@ -4456,8 +4747,14 @@ getObjectIdentityParts(const ObjectAddress *object,
object->objectId);
if (!HeapTupleIsValid(tup))
- elog(ERROR, "could not find tuple for cast %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "could not find tuple for cast %u",
+ object->objectId);
+
+ table_close(castRel, AccessShareLock);
+ break;
+ }
castForm = (Form_pg_cast) GETSTRUCT(tup);
@@ -4484,8 +4781,12 @@ getObjectIdentityParts(const ObjectAddress *object,
collTup = SearchSysCache1(COLLOID,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(collTup))
- elog(ERROR, "cache lookup failed for collation %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for collation %u",
+ object->objectId);
+ break;
+ }
coll = (Form_pg_collation) GETSTRUCT(collTup);
schema = get_namespace_name_or_temp(coll->collnamespace);
appendStringInfoString(&buffer,
@@ -4506,15 +4807,20 @@ getObjectIdentityParts(const ObjectAddress *object,
conTup = SearchSysCache1(CONSTROID,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(conTup))
- elog(ERROR, "cache lookup failed for constraint %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for constraint %u",
+ object->objectId);
+ break;
+ }
con = (Form_pg_constraint) GETSTRUCT(conTup);
if (OidIsValid(con->conrelid))
{
appendStringInfo(&buffer, "%s on ",
quote_identifier(NameStr(con->conname)));
- getRelationIdentity(&buffer, con->conrelid, objname);
+ getRelationIdentity(&buffer, con->conrelid, objname,
+ false);
if (objname)
*objname = lappend(*objname, pstrdup(NameStr(con->conname)));
}
@@ -4529,7 +4835,8 @@ getObjectIdentityParts(const ObjectAddress *object,
appendStringInfo(&buffer, "%s on %s",
quote_identifier(NameStr(con->conname)),
- getObjectIdentityParts(&domain, objname, objargs));
+ getObjectIdentityParts(&domain, objname,
+ objargs, false));
if (objname)
*objargs = lappend(*objargs, pstrdup(NameStr(con->conname)));
@@ -4548,8 +4855,12 @@ getObjectIdentityParts(const ObjectAddress *object,
conTup = SearchSysCache1(CONVOID,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(conTup))
- elog(ERROR, "cache lookup failed for conversion %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for conversion %u",
+ object->objectId);
+ break;
+ }
conForm = (Form_pg_conversion) GETSTRUCT(conTup);
schema = get_namespace_name_or_temp(conForm->connamespace);
appendStringInfoString(&buffer,
@@ -4585,8 +4896,15 @@ getObjectIdentityParts(const ObjectAddress *object,
tup = systable_getnext(adscan);
if (!HeapTupleIsValid(tup))
- elog(ERROR, "could not find tuple for attrdef %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "could not find tuple for attrdef %u",
+ object->objectId);
+
+ systable_endscan(adscan);
+ table_close(attrdefDesc, AccessShareLock);
+ break;
+ }
attrdef = (Form_pg_attrdef) GETSTRUCT(tup);
@@ -4596,7 +4914,8 @@ getObjectIdentityParts(const ObjectAddress *object,
appendStringInfo(&buffer, "for %s",
getObjectIdentityParts(&colobject,
- objname, objargs));
+ objname, objargs,
+ false));
systable_endscan(adscan);
table_close(attrdefDesc, AccessShareLock);
@@ -4611,8 +4930,12 @@ getObjectIdentityParts(const ObjectAddress *object,
langTup = SearchSysCache1(LANGOID,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(langTup))
- elog(ERROR, "cache lookup failed for language %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for language %u",
+ object->objectId);
+ break;
+ }
langForm = (Form_pg_language) GETSTRUCT(langTup);
appendStringInfoString(&buffer,
quote_identifier(NameStr(langForm->lanname)));
@@ -4622,6 +4945,8 @@ getObjectIdentityParts(const ObjectAddress *object,
break;
}
case OCLASS_LARGEOBJECT:
+ if (!LargeObjectExists(object->objectId))
+ break;
appendStringInfo(&buffer, "%u",
object->objectId);
if (objname)
@@ -4629,11 +4954,18 @@ getObjectIdentityParts(const ObjectAddress *object,
break;
case OCLASS_OPERATOR:
- appendStringInfoString(&buffer,
- format_operator_qualified(object->objectId));
- if (objname)
- format_operator_parts(object->objectId, objname, objargs);
- break;
+ {
+ bits16 flags = FORMAT_OPERATOR_FORCE_QUALIFY | FORMAT_OPERATOR_INVALID_AS_NULL;
+ char *oprname = format_operator_extended(object->objectId,
+ flags);
+ if (oprname == NULL)
+ break;
+
+ appendStringInfoString(&buffer, oprname);
+ if (objname)
+ format_operator_parts(object->objectId, objname, objargs, missing_ok);
+ break;
+ }
case OCLASS_OPCLASS:
{
@@ -4646,8 +4978,12 @@ getObjectIdentityParts(const ObjectAddress *object,
opcTup = SearchSysCache1(CLAOID,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(opcTup))
- elog(ERROR, "cache lookup failed for opclass %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for opclass %u",
+ object->objectId);
+ break;
+ }
opcForm = (Form_pg_opclass) GETSTRUCT(opcTup);
schema = get_namespace_name_or_temp(opcForm->opcnamespace);
@@ -4673,7 +5009,8 @@ getObjectIdentityParts(const ObjectAddress *object,
}
case OCLASS_OPFAMILY:
- getOpFamilyIdentity(&buffer, object->objectId, objname);
+ getOpFamilyIdentity(&buffer, object->objectId, objname,
+ missing_ok);
break;
case OCLASS_AM:
@@ -4682,8 +5019,12 @@ getObjectIdentityParts(const ObjectAddress *object,
amname = get_am_name(object->objectId);
if (!amname)
- elog(ERROR, "cache lookup failed for access method %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for access method %u",
+ object->objectId);
+ break;
+ }
appendStringInfoString(&buffer, quote_identifier(amname));
if (objname)
*objname = list_make1(amname);
@@ -4715,13 +5056,21 @@ getObjectIdentityParts(const ObjectAddress *object,
tup = systable_getnext(amscan);
if (!HeapTupleIsValid(tup))
- elog(ERROR, "could not find tuple for amop entry %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "could not find tuple for amop entry %u",
+ object->objectId);
+
+ systable_endscan(amscan);
+ table_close(amopDesc, AccessShareLock);
+ break;
+ }
amopForm = (Form_pg_amop) GETSTRUCT(tup);
initStringInfo(&opfam);
- getOpFamilyIdentity(&opfam, amopForm->amopfamily, objname);
+ getOpFamilyIdentity(&opfam, amopForm->amopfamily, objname,
+ false);
ltype = format_type_be_qualified(amopForm->amoplefttype);
rtype = format_type_be_qualified(amopForm->amoprighttype);
@@ -4769,13 +5118,21 @@ getObjectIdentityParts(const ObjectAddress *object,
tup = systable_getnext(amscan);
if (!HeapTupleIsValid(tup))
- elog(ERROR, "could not find tuple for amproc entry %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "could not find tuple for amproc entry %u",
+ object->objectId);
+
+ systable_endscan(amscan);
+ table_close(amprocDesc, AccessShareLock);
+ break;
+ }
amprocForm = (Form_pg_amproc) GETSTRUCT(tup);
initStringInfo(&opfam);
- getOpFamilyIdentity(&opfam, amprocForm->amprocfamily, objname);
+ getOpFamilyIdentity(&opfam, amprocForm->amprocfamily, objname,
+ false);
ltype = format_type_be_qualified(amprocForm->amproclefttype);
rtype = format_type_be_qualified(amprocForm->amprocrighttype);
@@ -4810,14 +5167,20 @@ getObjectIdentityParts(const ObjectAddress *object,
object->objectId);
if (!HeapTupleIsValid(tup))
- elog(ERROR, "could not find tuple for rule %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "could not find tuple for rule %u",
+ object->objectId);
+
+ table_close(ruleDesc, AccessShareLock);
+ break;
+ }
rule = (Form_pg_rewrite) GETSTRUCT(tup);
appendStringInfo(&buffer, "%s on ",
quote_identifier(NameStr(rule->rulename)));
- getRelationIdentity(&buffer, rule->ev_class, objname);
+ getRelationIdentity(&buffer, rule->ev_class, objname, false);
if (objname)
*objname = lappend(*objname, pstrdup(NameStr(rule->rulename)));
@@ -4837,14 +5200,20 @@ getObjectIdentityParts(const ObjectAddress *object,
object->objectId);
if (!HeapTupleIsValid(tup))
- elog(ERROR, "could not find tuple for trigger %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "could not find tuple for trigger %u",
+ object->objectId);
+
+ table_close(trigDesc, AccessShareLock);
+ break;
+ }
trig = (Form_pg_trigger) GETSTRUCT(tup);
appendStringInfo(&buffer, "%s on ",
quote_identifier(NameStr(trig->tgname)));
- getRelationIdentity(&buffer, trig->tgrelid, objname);
+ getRelationIdentity(&buffer, trig->tgrelid, objname, false);
if (objname)
*objname = lappend(*objname, pstrdup(NameStr(trig->tgname)));
@@ -4858,8 +5227,12 @@ getObjectIdentityParts(const ObjectAddress *object,
nspname = get_namespace_name_or_temp(object->objectId);
if (!nspname)
- elog(ERROR, "cache lookup failed for namespace %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for namespace %u",
+ object->objectId);
+ break;
+ }
appendStringInfoString(&buffer,
quote_identifier(nspname));
if (objname)
@@ -4876,8 +5249,12 @@ getObjectIdentityParts(const ObjectAddress *object,
tup = SearchSysCache1(STATEXTOID,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(tup))
- elog(ERROR, "cache lookup failed for statistics object %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for statistics object %u",
+ object->objectId);
+ break;
+ }
formStatistic = (Form_pg_statistic_ext) GETSTRUCT(tup);
schema = get_namespace_name_or_temp(formStatistic->stxnamespace);
appendStringInfoString(&buffer,
@@ -4899,8 +5276,12 @@ getObjectIdentityParts(const ObjectAddress *object,
tup = SearchSysCache1(TSPARSEROID,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(tup))
- elog(ERROR, "cache lookup failed for text search parser %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for text search parser %u",
+ object->objectId);
+ break;
+ }
formParser = (Form_pg_ts_parser) GETSTRUCT(tup);
schema = get_namespace_name_or_temp(formParser->prsnamespace);
appendStringInfoString(&buffer,
@@ -4922,8 +5303,12 @@ getObjectIdentityParts(const ObjectAddress *object,
tup = SearchSysCache1(TSDICTOID,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(tup))
- elog(ERROR, "cache lookup failed for text search dictionary %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for text search dictionary %u",
+ object->objectId);
+ break;
+ }
formDict = (Form_pg_ts_dict) GETSTRUCT(tup);
schema = get_namespace_name_or_temp(formDict->dictnamespace);
appendStringInfoString(&buffer,
@@ -4945,8 +5330,12 @@ getObjectIdentityParts(const ObjectAddress *object,
tup = SearchSysCache1(TSTEMPLATEOID,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(tup))
- elog(ERROR, "cache lookup failed for text search template %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for text search template %u",
+ object->objectId);
+ break;
+ }
formTmpl = (Form_pg_ts_template) GETSTRUCT(tup);
schema = get_namespace_name_or_temp(formTmpl->tmplnamespace);
appendStringInfoString(&buffer,
@@ -4968,8 +5357,12 @@ getObjectIdentityParts(const ObjectAddress *object,
tup = SearchSysCache1(TSCONFIGOID,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(tup))
- elog(ERROR, "cache lookup failed for text search configuration %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for text search configuration %u",
+ object->objectId);
+ break;
+ }
formCfg = (Form_pg_ts_config) GETSTRUCT(tup);
schema = get_namespace_name_or_temp(formCfg->cfgnamespace);
appendStringInfoString(&buffer,
@@ -4986,7 +5379,9 @@ getObjectIdentityParts(const ObjectAddress *object,
{
char *username;
- username = GetUserNameFromId(object->objectId, false);
+ username = GetUserNameFromId(object->objectId, missing_ok);
+ if (!username)
+ break;
if (objname)
*objname = list_make1(username);
appendStringInfoString(&buffer,
@@ -5000,8 +5395,12 @@ getObjectIdentityParts(const ObjectAddress *object,
datname = get_database_name(object->objectId);
if (!datname)
- elog(ERROR, "cache lookup failed for database %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for database %u",
+ object->objectId);
+ break;
+ }
if (objname)
*objname = list_make1(datname);
appendStringInfoString(&buffer,
@@ -5015,8 +5414,12 @@ getObjectIdentityParts(const ObjectAddress *object,
tblspace = get_tablespace_name(object->objectId);
if (!tblspace)
- elog(ERROR, "cache lookup failed for tablespace %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for tablespace %u",
+ object->objectId);
+ break;
+ }
if (objname)
*objname = list_make1(tblspace);
appendStringInfoString(&buffer,
@@ -5028,10 +5431,14 @@ getObjectIdentityParts(const ObjectAddress *object,
{
ForeignDataWrapper *fdw;
- fdw = GetForeignDataWrapper(object->objectId);
- appendStringInfoString(&buffer, quote_identifier(fdw->fdwname));
- if (objname)
- *objname = list_make1(pstrdup(fdw->fdwname));
+ fdw = GetForeignDataWrapperExtended(object->objectId,
+ missing_ok);
+ if (fdw)
+ {
+ appendStringInfoString(&buffer, quote_identifier(fdw->fdwname));
+ if (objname)
+ *objname = list_make1(pstrdup(fdw->fdwname));
+ }
break;
}
@@ -5039,11 +5446,15 @@ getObjectIdentityParts(const ObjectAddress *object,
{
ForeignServer *srv;
- srv = GetForeignServer(object->objectId);
- appendStringInfoString(&buffer,
- quote_identifier(srv->servername));
- if (objname)
- *objname = list_make1(pstrdup(srv->servername));
+ srv = GetForeignServerExtended(object->objectId,
+ missing_ok);
+ if (srv)
+ {
+ appendStringInfoString(&buffer,
+ quote_identifier(srv->servername));
+ if (objname)
+ *objname = list_make1(pstrdup(srv->servername));
+ }
break;
}
@@ -5058,8 +5469,12 @@ getObjectIdentityParts(const ObjectAddress *object,
tup = SearchSysCache1(USERMAPPINGOID,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(tup))
- elog(ERROR, "cache lookup failed for user mapping %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for user mapping %u",
+ object->objectId);
+ break;
+ }
umform = (Form_pg_user_mapping) GETSTRUCT(tup);
useid = umform->umuser;
srv = GetForeignServer(umform->umserver);
@@ -5106,8 +5521,16 @@ getObjectIdentityParts(const ObjectAddress *object,
tup = systable_getnext(rcscan);
if (!HeapTupleIsValid(tup))
- elog(ERROR, "could not find tuple for default ACL %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "could not find tuple for default ACL %u",
+ object->objectId);
+
+ systable_endscan(rcscan);
+ table_close(defaclrel, AccessShareLock);
+ break;
+
+ }
defacl = (Form_pg_default_acl) GETSTRUCT(tup);
@@ -5169,8 +5592,12 @@ getObjectIdentityParts(const ObjectAddress *object,
extname = get_extension_name(object->objectId);
if (!extname)
- elog(ERROR, "cache lookup failed for extension %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for extension %u",
+ object->objectId);
+ break;
+ }
appendStringInfoString(&buffer, quote_identifier(extname));
if (objname)
*objname = list_make1(extname);
@@ -5189,8 +5616,12 @@ getObjectIdentityParts(const ObjectAddress *object,
tup = SearchSysCache1(EVENTTRIGGEROID,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(tup))
- elog(ERROR, "cache lookup failed for event trigger %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for event trigger %u",
+ object->objectId);
+ break;
+ }
trigForm = (Form_pg_event_trigger) GETSTRUCT(tup);
appendStringInfoString(&buffer,
quote_identifier(NameStr(trigForm->evtname)));
@@ -5210,14 +5641,20 @@ getObjectIdentityParts(const ObjectAddress *object,
object->objectId);
if (!HeapTupleIsValid(tup))
- elog(ERROR, "could not find tuple for policy %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "could not find tuple for policy %u",
+ object->objectId);
+
+ table_close(polDesc, AccessShareLock);
+ break;
+ }
policy = (Form_pg_policy) GETSTRUCT(tup);
appendStringInfo(&buffer, "%s on ",
quote_identifier(NameStr(policy->polname)));
- getRelationIdentity(&buffer, policy->polrelid, objname);
+ getRelationIdentity(&buffer, policy->polrelid, objname, false);
if (objname)
*objname = lappend(*objname, pstrdup(NameStr(policy->polname)));
@@ -5229,11 +5666,14 @@ getObjectIdentityParts(const ObjectAddress *object,
{
char *pubname;
- pubname = get_publication_name(object->objectId, false);
- appendStringInfoString(&buffer,
- quote_identifier(pubname));
- if (objname)
- *objname = list_make1(pubname);
+ pubname = get_publication_name(object->objectId, missing_ok);
+ if (pubname)
+ {
+ appendStringInfoString(&buffer,
+ quote_identifier(pubname));
+ if (objname)
+ *objname = list_make1(pubname);
+ }
break;
}
@@ -5246,13 +5686,17 @@ getObjectIdentityParts(const ObjectAddress *object,
tup = SearchSysCache1(PUBLICATIONREL,
ObjectIdGetDatum(object->objectId));
if (!HeapTupleIsValid(tup))
- elog(ERROR, "cache lookup failed for publication table %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for publication table %u",
+ object->objectId);
+ break;
+ }
prform = (Form_pg_publication_rel) GETSTRUCT(tup);
pubname = get_publication_name(prform->prpubid, false);
- getRelationIdentity(&buffer, prform->prrelid, objname);
+ getRelationIdentity(&buffer, prform->prrelid, objname, false);
appendStringInfo(&buffer, " in publication %s", pubname);
if (objargs)
@@ -5266,11 +5710,14 @@ getObjectIdentityParts(const ObjectAddress *object,
{
char *subname;
- subname = get_subscription_name(object->objectId, false);
- appendStringInfoString(&buffer,
- quote_identifier(subname));
- if (objname)
- *objname = list_make1(subname);
+ subname = get_subscription_name(object->objectId, missing_ok);
+ if (subname)
+ {
+ appendStringInfoString(&buffer,
+ quote_identifier(subname));
+ if (objname)
+ *objname = list_make1(subname);
+ }
break;
}
@@ -5289,8 +5736,14 @@ getObjectIdentityParts(const ObjectAddress *object,
object->objectId);
if (!HeapTupleIsValid(tup))
- elog(ERROR, "could not find tuple for transform %u",
- object->objectId);
+ {
+ if (!missing_ok)
+ elog(ERROR, "could not find tuple for transform %u",
+ object->objectId);
+
+ table_close(transformDesc, AccessShareLock);
+ break;
+ }
transform = (Form_pg_transform) GETSTRUCT(tup);
@@ -5316,20 +5769,34 @@ getObjectIdentityParts(const ObjectAddress *object,
*/
}
- /*
- * If a get_object_address representation was requested, make sure we are
- * providing one. We don't check objargs, because many of the cases above
- * leave it as NIL.
- */
- if (objname && *objname == NIL)
- elog(ERROR, "requested object address for unsupported object class %d: text result \"%s\"",
- (int) getObjectClass(object), buffer.data);
+ if (!missing_ok)
+ {
+ /*
+ * If a get_object_address() representation was requested, make sure
+ * we are providing one. We don't check objargs, because many of the
+ * cases above leave it as NIL.
+ */
+ if (objname && *objname == NIL)
+ elog(ERROR, "requested object address for unsupported object class %d: text result \"%s\"",
+ (int) getObjectClass(object), buffer.data);
+ }
+ else
+ {
+ /* an empty buffer is equivalent to no object found */
+ if (buffer.len == 0)
+ {
+ Assert((objname == NULL || *objname == NIL) &&
+ (objargs == NULL || *objargs == NIL));
+ return NULL;
+ }
+ }
return buffer.data;
}
static void
-getOpFamilyIdentity(StringInfo buffer, Oid opfid, List **object)
+getOpFamilyIdentity(StringInfo buffer, Oid opfid, List **object,
+ bool missing_ok)
{
HeapTuple opfTup;
Form_pg_opfamily opfForm;
@@ -5339,7 +5806,11 @@ getOpFamilyIdentity(StringInfo buffer, Oid opfid, List **object)
opfTup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfid));
if (!HeapTupleIsValid(opfTup))
- elog(ERROR, "cache lookup failed for opfamily %u", opfid);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for opfamily %u", opfid);
+ return;
+ }
opfForm = (Form_pg_opfamily) GETSTRUCT(opfTup);
amTup = SearchSysCache1(AMOID, ObjectIdGetDatum(opfForm->opfmethod));
@@ -5368,7 +5839,8 @@ getOpFamilyIdentity(StringInfo buffer, Oid opfid, List **object)
* StringInfo.
*/
static void
-getRelationIdentity(StringInfo buffer, Oid relid, List **object)
+getRelationIdentity(StringInfo buffer, Oid relid, List **object,
+ bool missing_ok)
{
HeapTuple relTup;
Form_pg_class relForm;
@@ -5377,7 +5849,14 @@ getRelationIdentity(StringInfo buffer, Oid relid, List **object)
relTup = SearchSysCache1(RELOID,
ObjectIdGetDatum(relid));
if (!HeapTupleIsValid(relTup))
- elog(ERROR, "cache lookup failed for relation %u", relid);
+ {
+ if (!missing_ok)
+ elog(ERROR, "cache lookup failed for relation %u", relid);
+
+ if (object)
+ *object = NIL;
+ return;
+ }
relForm = (Form_pg_class) GETSTRUCT(relTup);
schema = get_namespace_name_or_temp(relForm->relnamespace);