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.c219
1 files changed, 219 insertions, 0 deletions
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index 2b1808b0f92..44d14ae2b18 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -45,7 +45,10 @@
#include "catalog/pg_operator.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_policy.h"
+#include "catalog/pg_publication.h"
+#include "catalog/pg_publication_rel.h"
#include "catalog/pg_rewrite.h"
+#include "catalog/pg_subscription.h"
#include "catalog/pg_tablespace.h"
#include "catalog/pg_transform.h"
#include "catalog/pg_trigger.h"
@@ -450,6 +453,30 @@ static const ObjectPropertyType ObjectProperty[] =
Anum_pg_type_typacl,
ACL_KIND_TYPE,
true
+ },
+ {
+ PublicationRelationId,
+ PublicationObjectIndexId,
+ PUBLICATIONOID,
+ PUBLICATIONNAME,
+ Anum_pg_publication_pubname,
+ InvalidAttrNumber,
+ Anum_pg_publication_pubowner,
+ InvalidAttrNumber,
+ -1,
+ true
+ },
+ {
+ SubscriptionRelationId,
+ SubscriptionObjectIndexId,
+ SUBSCRIPTIONOID,
+ SUBSCRIPTIONNAME,
+ Anum_pg_subscription_subname,
+ InvalidAttrNumber,
+ Anum_pg_subscription_subowner,
+ InvalidAttrNumber,
+ -1,
+ true
}
};
@@ -653,6 +680,18 @@ static const struct object_type_map
{
"policy", OBJECT_POLICY
},
+ /* OCLASS_PUBLICATION */
+ {
+ "publication", OBJECT_PUBLICATION
+ },
+ /* OCLASS_PUBLICATION_REL */
+ {
+ "publication relation", OBJECT_PUBLICATION_REL
+ },
+ /* OCLASS_SUBSCRIPTION */
+ {
+ "subscription", OBJECT_SUBSCRIPTION
+ },
/* OCLASS_TRANSFORM */
{
"transform", OBJECT_TRANSFORM
@@ -688,6 +727,9 @@ static ObjectAddress get_object_address_opf_member(ObjectType objtype,
static ObjectAddress get_object_address_usermapping(List *objname,
List *objargs, bool missing_ok);
+static ObjectAddress get_object_address_publication_rel(List *objname,
+ List *objargs, Relation *relation,
+ bool missing_ok);
static ObjectAddress get_object_address_defacl(List *objname, List *objargs,
bool missing_ok);
static const ObjectPropertyType *get_object_property_data(Oid class_id);
@@ -812,6 +854,8 @@ get_object_address(ObjectType objtype, List *objname, List *objargs,
case OBJECT_FOREIGN_SERVER:
case OBJECT_EVENT_TRIGGER:
case OBJECT_ACCESS_METHOD:
+ case OBJECT_PUBLICATION:
+ case OBJECT_SUBSCRIPTION:
address = get_object_address_unqualified(objtype,
objname, missing_ok);
break;
@@ -926,6 +970,10 @@ get_object_address(ObjectType objtype, List *objname, List *objargs,
address = get_object_address_usermapping(objname, objargs,
missing_ok);
break;
+ case OBJECT_PUBLICATION_REL:
+ address = get_object_address_publication_rel(objname, objargs,
+ &relation,
+ missing_ok);
case OBJECT_DEFACL:
address = get_object_address_defacl(objname, objargs,
missing_ok);
@@ -1091,6 +1139,12 @@ get_object_address_unqualified(ObjectType objtype,
case OBJECT_EVENT_TRIGGER:
msg = gettext_noop("event trigger name cannot be qualified");
break;
+ case OBJECT_PUBLICATION:
+ msg = gettext_noop("publication name cannot be qualified");
+ break;
+ case OBJECT_SUBSCRIPTION:
+ msg = gettext_noop("subscription name cannot be qualified");
+ break;
default:
elog(ERROR, "unrecognized objtype: %d", (int) objtype);
msg = NULL; /* placate compiler */
@@ -1156,6 +1210,16 @@ get_object_address_unqualified(ObjectType objtype,
address.objectId = get_event_trigger_oid(name, missing_ok);
address.objectSubId = 0;
break;
+ case OBJECT_PUBLICATION:
+ address.classId = PublicationRelationId;
+ address.objectId = get_publication_oid(name, missing_ok);
+ address.objectSubId = 0;
+ break;
+ case OBJECT_SUBSCRIPTION:
+ address.classId = SubscriptionRelationId;
+ address.objectId = get_subscription_oid(name, missing_ok);
+ address.objectSubId = 0;
+ break;
default:
elog(ERROR, "unrecognized objtype: %d", (int) objtype);
/* placate compiler, which doesn't know elog won't return */
@@ -1744,6 +1808,51 @@ get_object_address_usermapping(List *objname, List *objargs, bool missing_ok)
}
/*
+ * Find the ObjectAddress for a publication relation. The objname parameter
+ * is the relation name; objargs contains the publication name.
+ */
+static ObjectAddress
+get_object_address_publication_rel(List *objname, List *objargs,
+ Relation *relation, bool missing_ok)
+{
+ ObjectAddress address;
+ char *pubname;
+ Publication *pub;
+
+ ObjectAddressSet(address, PublicationRelRelationId, InvalidOid);
+
+ *relation = relation_openrv_extended(makeRangeVarFromNameList(objname),
+ AccessShareLock, missing_ok);
+ if (!relation)
+ return address;
+
+ /* fetch publication name from input list */
+ pubname = strVal(linitial(objargs));
+
+ /* Now look up the pg_publication tuple */
+ pub = GetPublicationByName(pubname, missing_ok);
+ if (!pub)
+ return address;
+
+ /* Find the publication relation mapping in syscache. */
+ address.objectId =
+ GetSysCacheOid2(PUBLICATIONRELMAP,
+ ObjectIdGetDatum(RelationGetRelid(*relation)),
+ ObjectIdGetDatum(pub->oid));
+ if (!OidIsValid(address.objectId))
+ {
+ if (!missing_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("publication relation \"%s\" in publication \"%s\" does not exist",
+ RelationGetRelationName(*relation), pubname)));
+ return address;
+ }
+
+ return address;
+}
+
+/*
* Find the ObjectAddress for a default ACL.
*/
static ObjectAddress
@@ -2002,6 +2111,7 @@ pg_get_object_address(PG_FUNCTION_ARGS)
case OBJECT_DOMCONSTRAINT:
case OBJECT_CAST:
case OBJECT_USER_MAPPING:
+ case OBJECT_PUBLICATION_REL:
case OBJECT_DEFACL:
case OBJECT_TRANSFORM:
if (list_length(args) != 1)
@@ -2183,6 +2293,16 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address,
format_type_be(targettypeid))));
}
break;
+ case OBJECT_PUBLICATION:
+ if (!pg_publication_ownercheck(address.objectId, roleid))
+ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PUBLICATION,
+ NameListToString(objname));
+ break;
+ case OBJECT_SUBSCRIPTION:
+ if (!pg_subscription_ownercheck(address.objectId, roleid))
+ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_SUBSCRIPTION,
+ NameListToString(objname));
+ break;
case OBJECT_TRANSFORM:
{
TypeName *typename = (TypeName *) linitial(objname);
@@ -3191,6 +3311,41 @@ getObjectDescription(const ObjectAddress *object)
break;
}
+ case OCLASS_PUBLICATION:
+ {
+ appendStringInfo(&buffer, _("publication %s"),
+ get_publication_name(object->objectId));
+ break;
+ }
+
+ case OCLASS_PUBLICATION_REL:
+ {
+ HeapTuple tup;
+ char *pubname;
+ Form_pg_publication_rel prform;
+
+ tup = SearchSysCache1(PUBLICATIONREL,
+ ObjectIdGetDatum(object->objectId));
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "cache lookup failed for publication table %u",
+ object->objectId);
+
+ prform = (Form_pg_publication_rel) GETSTRUCT(tup);
+ pubname = get_publication_name(prform->prpubid);
+
+ appendStringInfo(&buffer, _("publication table %s in publication %s"),
+ get_rel_name(prform->prrelid), pubname);
+ ReleaseSysCache(tup);
+ break;
+ }
+
+ case OCLASS_SUBSCRIPTION:
+ {
+ appendStringInfo(&buffer, _("subscription %s"),
+ get_subscription_name(object->objectId));
+ break;
+ }
+
default:
appendStringInfo(&buffer, "unrecognized object %u %u %d",
object->classId,
@@ -3677,6 +3832,18 @@ getObjectTypeDescription(const ObjectAddress *object)
appendStringInfoString(&buffer, "access method");
break;
+ case OCLASS_PUBLICATION:
+ appendStringInfoString(&buffer, "publication");
+ break;
+
+ case OCLASS_PUBLICATION_REL:
+ appendStringInfoString(&buffer, "publication table");
+ break;
+
+ case OCLASS_SUBSCRIPTION:
+ appendStringInfoString(&buffer, "subscription");
+ break;
+
default:
appendStringInfo(&buffer, "unrecognized %u", object->classId);
break;
@@ -4648,6 +4815,58 @@ getObjectIdentityParts(const ObjectAddress *object,
}
break;
+ case OCLASS_PUBLICATION:
+ {
+ char *pubname;
+
+ pubname = get_publication_name(object->objectId);
+ appendStringInfoString(&buffer,
+ quote_identifier(pubname));
+ if (objname)
+ *objname = list_make1(pubname);
+ break;
+ }
+
+ case OCLASS_PUBLICATION_REL:
+ {
+ HeapTuple tup;
+ char *pubname;
+ Form_pg_publication_rel prform;
+
+ tup = SearchSysCache1(PUBLICATIONREL,
+ ObjectIdGetDatum(object->objectId));
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "cache lookup failed for publication table %u",
+ object->objectId);
+
+ prform = (Form_pg_publication_rel) GETSTRUCT(tup);
+ pubname = get_publication_name(prform->prpubid);
+
+ appendStringInfo(&buffer, _("publication table %s in publication %s"),
+ get_rel_name(prform->prrelid), pubname);
+
+ if (objname)
+ {
+ getRelationIdentity(&buffer, prform->prrelid, objname);
+ *objargs = list_make1(pubname);
+ }
+
+ ReleaseSysCache(tup);
+ break;
+ }
+
+ case OCLASS_SUBSCRIPTION:
+ {
+ char *subname;
+
+ subname = get_subscription_name(object->objectId);
+ appendStringInfoString(&buffer,
+ quote_identifier(subname));
+ if (objname)
+ *objname = list_make1(subname);
+ break;
+ }
+
default:
appendStringInfo(&buffer, "unrecognized object %u %u %d",
object->classId,