aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/catalog/heap.c2
-rw-r--r--src/backend/catalog/pg_collation.c2
-rw-r--r--src/backend/catalog/pg_conversion.c2
-rw-r--r--src/backend/catalog/pg_depend.c32
-rw-r--r--src/backend/catalog/pg_namespace.c2
-rw-r--r--src/backend/catalog/pg_operator.c2
-rw-r--r--src/backend/catalog/pg_proc.c6
-rw-r--r--src/backend/catalog/pg_type.c11
-rw-r--r--src/backend/commands/foreigncmds.c6
-rw-r--r--src/backend/commands/functioncmds.c10
-rw-r--r--src/backend/commands/opclasscmds.c4
-rw-r--r--src/backend/commands/proclang.c6
-rw-r--r--src/backend/commands/tsearchcmds.c9
-rw-r--r--src/include/catalog/dependency.h3
14 files changed, 61 insertions, 36 deletions
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 7cf44d1f256..43994936257 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -1256,7 +1256,7 @@ heap_create_with_catalog(const char *relname,
recordDependencyOnOwner(RelationRelationId, relid, ownerid);
- recordDependencyOnCurrentExtension(&myself);
+ recordDependencyOnCurrentExtension(&myself, false);
if (reloftypeid)
{
diff --git a/src/backend/catalog/pg_collation.c b/src/backend/catalog/pg_collation.c
index 28a016b9726..ce9bfae7025 100644
--- a/src/backend/catalog/pg_collation.c
+++ b/src/backend/catalog/pg_collation.c
@@ -132,7 +132,7 @@ CollationCreate(const char *collname, Oid collnamespace,
collowner);
/* dependency on extension */
- recordDependencyOnCurrentExtension(&myself);
+ recordDependencyOnCurrentExtension(&myself, false);
/* Post creation hook for new collation */
InvokeObjectAccessHook(OAT_POST_CREATE,
diff --git a/src/backend/catalog/pg_conversion.c b/src/backend/catalog/pg_conversion.c
index 1ef6a9d24e2..c84dbc6ae4c 100644
--- a/src/backend/catalog/pg_conversion.c
+++ b/src/backend/catalog/pg_conversion.c
@@ -133,7 +133,7 @@ ConversionCreate(const char *conname, Oid connamespace,
conowner);
/* dependency on extension */
- recordDependencyOnCurrentExtension(&myself);
+ recordDependencyOnCurrentExtension(&myself, false);
/* Post creation hook for new conversion */
InvokeObjectAccessHook(OAT_POST_CREATE,
diff --git a/src/backend/catalog/pg_depend.c b/src/backend/catalog/pg_depend.c
index 67aad86d4e7..c1a4340190a 100644
--- a/src/backend/catalog/pg_depend.c
+++ b/src/backend/catalog/pg_depend.c
@@ -130,14 +130,44 @@ recordMultipleDependencies(const ObjectAddress *depender,
*
* This must be called during creation of any user-definable object type
* that could be a member of an extension.
+ *
+ * If isReplace is true, the object already existed (or might have already
+ * existed), so we must check for a pre-existing extension membership entry.
+ * Passing false is a guarantee that the object is newly created, and so
+ * could not already be a member of any extension.
*/
void
-recordDependencyOnCurrentExtension(const ObjectAddress *object)
+recordDependencyOnCurrentExtension(const ObjectAddress *object,
+ bool isReplace)
{
+ /* Only whole objects can be extension members */
+ Assert(object->objectSubId == 0);
+
if (creating_extension)
{
ObjectAddress extension;
+ /* Only need to check for existing membership if isReplace */
+ if (isReplace)
+ {
+ Oid oldext;
+
+ oldext = getExtensionOfObject(object->classId, object->objectId);
+ if (OidIsValid(oldext))
+ {
+ /* If already a member of this extension, nothing to do */
+ if (oldext == CurrentExtensionObject)
+ return;
+ /* Already a member of some other extension, so reject */
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("%s is already a member of extension \"%s\"",
+ getObjectDescription(object),
+ get_extension_name(oldext))));
+ }
+ }
+
+ /* OK, record it as a member of CurrentExtensionObject */
extension.classId = ExtensionRelationId;
extension.objectId = CurrentExtensionObject;
extension.objectSubId = 0;
diff --git a/src/backend/catalog/pg_namespace.c b/src/backend/catalog/pg_namespace.c
index 172f99196cc..ceebac2f7e1 100644
--- a/src/backend/catalog/pg_namespace.c
+++ b/src/backend/catalog/pg_namespace.c
@@ -83,7 +83,7 @@ NamespaceCreate(const char *nspName, Oid ownerId)
recordDependencyOnOwner(NamespaceRelationId, nspoid, ownerId);
/* dependency on extension */
- recordDependencyOnCurrentExtension(&myself);
+ recordDependencyOnCurrentExtension(&myself, false);
/* Post creation hook for new schema */
InvokeObjectAccessHook(OAT_POST_CREATE, NamespaceRelationId, nspoid, 0);
diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c
index 4d2d7b7e265..772e5d438d1 100644
--- a/src/backend/catalog/pg_operator.c
+++ b/src/backend/catalog/pg_operator.c
@@ -855,5 +855,5 @@ makeOperatorDependencies(HeapTuple tuple)
oper->oprowner);
/* Dependency on extension */
- recordDependencyOnCurrentExtension(&myself);
+ recordDependencyOnCurrentExtension(&myself, true);
}
diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
index ec229810cac..f2f08721599 100644
--- a/src/backend/catalog/pg_proc.c
+++ b/src/backend/catalog/pg_proc.c
@@ -564,8 +564,7 @@ ProcedureCreate(const char *procedureName,
* Create dependencies for the new function. If we are updating an
* existing function, first delete any existing pg_depend entries.
* (However, since we are not changing ownership or permissions, the
- * shared dependencies do *not* need to change, and we leave them alone.
- * We also don't change any pre-existing extension-membership dependency.)
+ * shared dependencies do *not* need to change, and we leave them alone.)
*/
if (is_update)
deleteDependencyRecordsFor(ProcedureRelationId, retval, true);
@@ -619,8 +618,7 @@ ProcedureCreate(const char *procedureName,
}
/* dependency on extension */
- if (!is_update)
- recordDependencyOnCurrentExtension(&myself);
+ recordDependencyOnCurrentExtension(&myself, is_update);
heap_freetuple(tup);
diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c
index f6082298239..ea52f67dabb 100644
--- a/src/backend/catalog/pg_type.c
+++ b/src/backend/catalog/pg_type.c
@@ -480,7 +480,7 @@ TypeCreate(Oid newTypeOid,
*
* If rebuild is true, we remove existing dependencies and rebuild them
* from scratch. This is needed for ALTER TYPE, and also when replacing
- * a shell type. We don't remove/rebuild extension dependencies, though.
+ * a shell type.
*/
void
GenerateTypeDependencies(Oid typeNamespace,
@@ -521,7 +521,7 @@ GenerateTypeDependencies(Oid typeNamespace,
* For a relation rowtype (that's not a composite type), we should skip
* these because we'll depend on them indirectly through the pg_class
* entry. Likewise, skip for implicit arrays since we'll depend on them
- * through the element type. The same goes for extension membership.
+ * through the element type.
*/
if ((!OidIsValid(relationOid) || relationKind == RELKIND_COMPOSITE_TYPE) &&
!isImplicitArray)
@@ -532,12 +532,11 @@ GenerateTypeDependencies(Oid typeNamespace,
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
recordDependencyOnOwner(TypeRelationId, typeObjectId, owner);
-
- /* dependency on extension */
- if (!rebuild)
- recordDependencyOnCurrentExtension(&myself);
}
+ /* dependency on extension */
+ recordDependencyOnCurrentExtension(&myself, rebuild);
+
/* Normal dependencies on the I/O functions */
if (OidIsValid(inputProcedure))
{
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index 643ba91bfe1..d16932ba6a0 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -515,7 +515,7 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt)
recordDependencyOnOwner(ForeignDataWrapperRelationId, fdwId, ownerId);
/* dependency on extension */
- recordDependencyOnCurrentExtension(&myself);
+ recordDependencyOnCurrentExtension(&myself, false);
/* Post creation hook for new foreign data wrapper */
InvokeObjectAccessHook(OAT_POST_CREATE,
@@ -857,7 +857,7 @@ CreateForeignServer(CreateForeignServerStmt *stmt)
recordDependencyOnOwner(ForeignServerRelationId, srvId, ownerId);
/* dependency on extension */
- recordDependencyOnCurrentExtension(&myself);
+ recordDependencyOnCurrentExtension(&myself, false);
/* Post creation hook for new foreign server */
InvokeObjectAccessHook(OAT_POST_CREATE, ForeignServerRelationId, srvId, 0);
@@ -1137,7 +1137,7 @@ CreateUserMapping(CreateUserMappingStmt *stmt)
}
/* dependency on extension */
- recordDependencyOnCurrentExtension(&myself);
+ recordDependencyOnCurrentExtension(&myself, false);
/* Post creation hook for new user mapping */
InvokeObjectAccessHook(OAT_POST_CREATE, UserMappingRelationId, umId, 0);
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 03da168ff2c..92abd44a600 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -1489,6 +1489,7 @@ CreateCast(CreateCastStmt *stmt)
char sourcetyptype;
char targettyptype;
Oid funcid;
+ Oid castid;
int nargs;
char castcontext;
char castmethod;
@@ -1734,13 +1735,13 @@ CreateCast(CreateCastStmt *stmt)
tuple = heap_form_tuple(RelationGetDescr(relation), values, nulls);
- simple_heap_insert(relation, tuple);
+ castid = simple_heap_insert(relation, tuple);
CatalogUpdateIndexes(relation, tuple);
/* make dependency entries */
myself.classId = CastRelationId;
- myself.objectId = HeapTupleGetOid(tuple);
+ myself.objectId = castid;
myself.objectSubId = 0;
/* dependency on source type */
@@ -1765,11 +1766,10 @@ CreateCast(CreateCastStmt *stmt)
}
/* dependency on extension */
- recordDependencyOnCurrentExtension(&myself);
+ recordDependencyOnCurrentExtension(&myself, false);
/* Post creation hook for new cast */
- InvokeObjectAccessHook(OAT_POST_CREATE,
- CastRelationId, myself.objectId, 0);
+ InvokeObjectAccessHook(OAT_POST_CREATE, CastRelationId, castid, 0);
heap_freetuple(tuple);
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index aff5ac6ec43..2bb0d4c3b5f 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -310,7 +310,7 @@ CreateOpFamily(char *amname, char *opfname, Oid namespaceoid, Oid amoid)
recordDependencyOnOwner(OperatorFamilyRelationId, opfamilyoid, GetUserId());
/* dependency on extension */
- recordDependencyOnCurrentExtension(&myself);
+ recordDependencyOnCurrentExtension(&myself, false);
/* Post creation hook for new operator family */
InvokeObjectAccessHook(OAT_POST_CREATE,
@@ -713,7 +713,7 @@ DefineOpClass(CreateOpClassStmt *stmt)
recordDependencyOnOwner(OperatorClassRelationId, opclassoid, GetUserId());
/* dependency on extension */
- recordDependencyOnCurrentExtension(&myself);
+ recordDependencyOnCurrentExtension(&myself, false);
/* Post creation hook for new operator class */
InvokeObjectAccessHook(OAT_POST_CREATE,
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index b36f31ee6d5..98770c5a61a 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -388,8 +388,7 @@ create_proc_lang(const char *languageName, bool replace,
* Create dependencies for the new language. If we are updating an
* existing language, first delete any existing pg_depend entries.
* (However, since we are not changing ownership or permissions, the
- * shared dependencies do *not* need to change, and we leave them alone.
- * We also don't change any pre-existing extension-membership dependency.)
+ * shared dependencies do *not* need to change, and we leave them alone.)
*/
myself.classId = LanguageRelationId;
myself.objectId = HeapTupleGetOid(tup);
@@ -404,8 +403,7 @@ create_proc_lang(const char *languageName, bool replace,
languageOwner);
/* dependency on extension */
- if (!is_update)
- recordDependencyOnCurrentExtension(&myself);
+ recordDependencyOnCurrentExtension(&myself, is_update);
/* dependency on the PL handler function */
referenced.classId = ProcedureRelationId;
diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c
index 3355eaafda2..deac1062ef9 100644
--- a/src/backend/commands/tsearchcmds.c
+++ b/src/backend/commands/tsearchcmds.c
@@ -142,7 +142,7 @@ makeParserDependencies(HeapTuple tuple)
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
/* dependency on extension */
- recordDependencyOnCurrentExtension(&myself);
+ recordDependencyOnCurrentExtension(&myself, false);
/* dependencies on functions */
referenced.classId = ProcedureRelationId;
@@ -479,7 +479,7 @@ makeDictionaryDependencies(HeapTuple tuple)
recordDependencyOnOwner(myself.classId, myself.objectId, dict->dictowner);
/* dependency on extension */
- recordDependencyOnCurrentExtension(&myself);
+ recordDependencyOnCurrentExtension(&myself, false);
/* dependency on template */
referenced.classId = TSTemplateRelationId;
@@ -1069,7 +1069,7 @@ makeTSTemplateDependencies(HeapTuple tuple)
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
/* dependency on extension */
- recordDependencyOnCurrentExtension(&myself);
+ recordDependencyOnCurrentExtension(&myself, false);
/* dependencies on functions */
referenced.classId = ProcedureRelationId;
@@ -1417,8 +1417,7 @@ makeConfigurationDependencies(HeapTuple tuple, bool removeOld,
recordDependencyOnOwner(myself.classId, myself.objectId, cfg->cfgowner);
/* dependency on extension */
- if (!removeOld)
- recordDependencyOnCurrentExtension(&myself);
+ recordDependencyOnCurrentExtension(&myself, removeOld);
/* dependency on parser */
referenced.classId = TSParserRelationId;
diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h
index a3bd729156f..5dfb25fee74 100644
--- a/src/include/catalog/dependency.h
+++ b/src/include/catalog/dependency.h
@@ -201,7 +201,8 @@ extern void recordMultipleDependencies(const ObjectAddress *depender,
int nreferenced,
DependencyType behavior);
-extern void recordDependencyOnCurrentExtension(const ObjectAddress *object);
+extern void recordDependencyOnCurrentExtension(const ObjectAddress *object,
+ bool isReplace);
extern long deleteDependencyRecordsFor(Oid classId, Oid objectId,
bool skipExtensionDeps);