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
membernum,
TypeNameToString(typenames[0]),
TypeNameToString(typenames[1]),
- getObjectDescription(&famaddr))));
+ getObjectDescription(&famaddr, false))));
}
else
{
membernum,
TypeNameToString(typenames[0]),
TypeNameToString(typenames[1]),
- getObjectDescription(&famaddr))));
+ getObjectDescription(&famaddr, false))));
}
else
{
/*
* 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;
{
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:
{
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);
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 */
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))
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);
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 */
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);
/* 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);
}
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:
{
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,
}
case OCLASS_OPFAMILY:
- getOpFamilyDescription(&buffer, object->objectId);
+ getOpFamilyDescription(&buffer, object->objectId, missing_ok);
break;
case OCLASS_AM:
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);
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
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
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"),
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"),
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;
}
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 */
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 */
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 */
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 */
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 */
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;
}
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;
}
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;
}
{
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;
}
{
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;
}
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);
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);
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;
}
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);
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"),
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;
}
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"),
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;
}
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);
*/
}
+ /* an empty buffer is equivalent to no object found */
+ if (buffer.len == 0)
+ return NULL;
+
return buffer.data;
}
address.objectId = objid;
address.objectSubId = 0;
- return getObjectDescription(&address);
+ return getObjectDescription(&address, false);
}
/*
* 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;
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 */
* 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;
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));
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));
}
int32 objsubid = PG_GETARG_INT32(2);
Oid schema_oid = InvalidOid;
const char *objname = NULL;
+ char *objidentity;
ObjectAddress address;
Datum values[4];
bool nulls[4];
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));
nulls[1] = true;
/* object name */
- if (objname)
+ if (objname && objidentity)
{
values[2] = CStringGetTextDatum(objname);
nulls[2] = false;
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);
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);
* Keep ObjectTypeMap in sync with this.
*/
char *
-getObjectTypeDescription(const ObjectAddress *object)
+getObjectTypeDescription(const ObjectAddress *object, bool missing_ok)
{
StringInfoData buffer;
{
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:
break;
case OCLASS_CONSTRAINT:
- getConstraintTypeDescription(&buffer, object->objectId);
+ getConstraintTypeDescription(&buffer, object->objectId,
+ missing_ok);
break;
case OCLASS_CONVERSION:
*/
}
+ /* an empty string is equivalent to no object found */
+ if (buffer.len == 0)
+ return NULL;
+
return buffer.data;
}
* 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;
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)
* 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;
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);
* 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;
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)
* 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);
}
/*
* 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;
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);
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);
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,
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)));
}
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)));
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,
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);
appendStringInfo(&buffer, "for %s",
getObjectIdentityParts(&colobject,
- objname, objargs));
+ objname, objargs,
+ false));
systable_endscan(adscan);
table_close(attrdefDesc, AccessShareLock);
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)));
break;
}
case OCLASS_LARGEOBJECT:
+ if (!LargeObjectExists(object->objectId))
+ break;
appendStringInfo(&buffer, "%u",
object->objectId);
if (objname)
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:
{
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);
}
case OCLASS_OPFAMILY:
- getOpFamilyIdentity(&buffer, object->objectId, objname);
+ getOpFamilyIdentity(&buffer, object->objectId, objname,
+ missing_ok);
break;
case OCLASS_AM:
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);
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);
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);
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)));
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)));
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)
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,
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,
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,
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,
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,
{
char *username;
- username = GetUserNameFromId(object->objectId, false);
+ username = GetUserNameFromId(object->objectId, missing_ok);
+ if (!username)
+ break;
if (objname)
*objname = list_make1(username);
appendStringInfoString(&buffer,
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,
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,
{
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;
}
{
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;
}
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);
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);
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);
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)));
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)));
{
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;
}
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)
{
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;
}
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);
*/
}
- /*
- * 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;
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));
* 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;
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);
drop cascades to function proc(integer)
DROP OWNED BY regress_addr_user;
DROP USER regress_addr_user;
+--
+-- Checks for invalid objects
+--
+-- Make sure that NULL handling is correct.
+\pset null 'NULL'
+-- Temporarily disable fancy output, so as future additions never create
+-- a large amount of diffs.
+\a\t
+-- Keep this list in the same order as getObjectIdentityParts()
+-- in objectaddress.c.
+WITH objects (classid, objid, objsubid) AS (VALUES
+ ('pg_class'::regclass, 0, 0), -- no relation
+ ('pg_class'::regclass, 'pg_class'::regclass, 100), -- no column for relation
+ ('pg_proc'::regclass, 0, 0), -- no function
+ ('pg_type'::regclass, 0, 0), -- no type
+ ('pg_cast'::regclass, 0, 0), -- no cast
+ ('pg_collation'::regclass, 0, 0), -- no collation
+ ('pg_constraint'::regclass, 0, 0), -- no constraint
+ ('pg_conversion'::regclass, 0, 0), -- no conversion
+ ('pg_attrdef'::regclass, 0, 0), -- no default attribute
+ ('pg_language'::regclass, 0, 0), -- no language
+ ('pg_largeobject'::regclass, 0, 0), -- no large object, no error
+ ('pg_operator'::regclass, 0, 0), -- no operator
+ ('pg_opclass'::regclass, 0, 0), -- no opclass, no need to check for no access method
+ ('pg_opfamily'::regclass, 0, 0), -- no opfamily
+ ('pg_am'::regclass, 0, 0), -- no access method
+ ('pg_amop'::regclass, 0, 0), -- no AM operator
+ ('pg_amproc'::regclass, 0, 0), -- no AM proc
+ ('pg_rewrite'::regclass, 0, 0), -- no rewrite
+ ('pg_trigger'::regclass, 0, 0), -- no trigger
+ ('pg_namespace'::regclass, 0, 0), -- no schema
+ ('pg_statistic_ext'::regclass, 0, 0), -- no statistics
+ ('pg_ts_parser'::regclass, 0, 0), -- no TS parser
+ ('pg_ts_dict'::regclass, 0, 0), -- no TS dictionnary
+ ('pg_ts_template'::regclass, 0, 0), -- no TS template
+ ('pg_ts_config'::regclass, 0, 0), -- no TS configuration
+ ('pg_authid'::regclass, 0, 0), -- no role
+ ('pg_database'::regclass, 0, 0), -- no database
+ ('pg_tablespace'::regclass, 0, 0), -- no tablespace
+ ('pg_foreign_data_wrapper'::regclass, 0, 0), -- no FDW
+ ('pg_foreign_server'::regclass, 0, 0), -- no server
+ ('pg_user_mapping'::regclass, 0, 0), -- no user mapping
+ ('pg_default_acl'::regclass, 0, 0), -- no default ACL
+ ('pg_extension'::regclass, 0, 0), -- no extension
+ ('pg_event_trigger'::regclass, 0, 0), -- no event trigger
+ ('pg_policy'::regclass, 0, 0), -- no policy
+ ('pg_publication'::regclass, 0, 0), -- no publication
+ ('pg_publication_rel'::regclass, 0, 0), -- no publication relation
+ ('pg_subscription'::regclass, 0, 0), -- no subscription
+ ('pg_transform'::regclass, 0, 0) -- no transformation
+ )
+SELECT ROW(pg_identify_object(objects.classid, objects.objid, objects.objsubid))
+ AS ident,
+ ROW(pg_identify_object_as_address(objects.classid, objects.objid, objects.objsubid))
+ AS addr,
+ pg_describe_object(objects.classid, objects.objid, objects.objsubid)
+ AS descr
+FROM objects
+ORDER BY objects.classid, objects.objid, objects.objsubid;
+("(""default acl"",,,)")|("(""default acl"",,)")|NULL
+("(tablespace,,,)")|("(tablespace,,)")|NULL
+("(type,,,)")|("(type,,)")|NULL
+("(routine,,,)")|("(routine,,)")|NULL
+("(relation,,,)")|("(relation,,)")|NULL
+("(""table column"",,,)")|("(""table column"",,)")|NULL
+("(role,,,)")|("(role,,)")|NULL
+("(database,,,)")|("(database,,)")|NULL
+("(server,,,)")|("(server,,)")|NULL
+("(""user mapping"",,,)")|("(""user mapping"",,)")|NULL
+("(""foreign-data wrapper"",,,)")|("(""foreign-data wrapper"",,)")|NULL
+("(""access method"",,,)")|("(""access method"",,)")|NULL
+("(""operator of access method"",,,)")|("(""operator of access method"",,)")|NULL
+("(""function of access method"",,,)")|("(""function of access method"",,)")|NULL
+("(""default value"",,,)")|("(""default value"",,)")|NULL
+("(cast,,,)")|("(cast,,)")|NULL
+("(constraint,,,)")|("(constraint,,)")|NULL
+("(conversion,,,)")|("(conversion,,)")|NULL
+("(language,,,)")|("(language,,)")|NULL
+("(""large object"",,,)")|("(""large object"",,)")|NULL
+("(schema,,,)")|("(schema,,)")|NULL
+("(""operator class"",,,)")|("(""operator class"",,)")|NULL
+("(operator,,,)")|("(operator,,)")|NULL
+("(rule,,,)")|("(rule,,)")|NULL
+("(trigger,,,)")|("(trigger,,)")|NULL
+("(""operator family"",,,)")|("(""operator family"",,)")|NULL
+("(extension,,,)")|("(extension,,)")|NULL
+("(policy,,,)")|("(policy,,)")|NULL
+("(""statistics object"",,,)")|("(""statistics object"",,)")|NULL
+("(collation,,,)")|("(collation,,)")|NULL
+("(""event trigger"",,,)")|("(""event trigger"",,)")|NULL
+("(transform,,,)")|("(transform,,)")|NULL
+("(""text search dictionary"",,,)")|("(""text search dictionary"",,)")|NULL
+("(""text search parser"",,,)")|("(""text search parser"",,)")|NULL
+("(""text search configuration"",,,)")|("(""text search configuration"",,)")|NULL
+("(""text search template"",,,)")|("(""text search template"",,)")|NULL
+("(subscription,,,)")|("(subscription,,)")|NULL
+("(publication,,,)")|("(publication,,)")|NULL
+("(""publication relation"",,,)")|("(""publication relation"",,)")|NULL
+-- restore normal output mode
+\a\t