aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2011-11-28 19:12:17 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2011-11-28 19:12:41 -0500
commitec3e183ec51bb2d4032be6d5402ddc7b4c8acb71 (patch)
tree45d6f75b7e3d736ddeb463b49bfde5acda3f3b31
parent8ab9df0db196b6e1afa75838394eb27e9955e80e (diff)
downloadpostgresql-ec3e183ec51bb2d4032be6d5402ddc7b4c8acb71.tar.gz
postgresql-ec3e183ec51bb2d4032be6d5402ddc7b4c8acb71.zip
Disallow deletion of CurrentExtensionObject while running extension script.
While the deletion in itself wouldn't break things, any further creation of objects in the script would result in dangling pg_depend entries being added by recordDependencyOnCurrentExtension(). An example from Phil Sorber convinced me that this is just barely likely enough to be worth expending a couple lines of code to defend against. The resulting error message might be confusing, but it's better than leaving corrupted catalog contents for the user to deal with.
-rw-r--r--src/backend/commands/extension.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index 024d4c8a009..63b3ffa4ef0 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -1642,6 +1642,23 @@ RemoveExtensionById(Oid extId)
HeapTuple tuple;
ScanKeyData entry[1];
+ /*
+ * Disallow deletion of any extension that's currently open for insertion;
+ * else subsequent executions of recordDependencyOnCurrentExtension()
+ * could create dangling pg_depend records that refer to a no-longer-valid
+ * pg_extension OID. This is needed not so much because we think people
+ * might write "DROP EXTENSION foo" in foo's own script files, as because
+ * errors in dependency management in extension script files could give
+ * rise to cases where an extension is dropped as a result of recursing
+ * from some contained object. Because of that, we must test for the case
+ * here, not at some higher level of the DROP EXTENSION command.
+ */
+ if (extId == CurrentExtensionObject)
+ ereport(ERROR,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("cannot drop extension \"%s\" because it is being modified",
+ get_extension_name(extId))));
+
rel = heap_open(ExtensionRelationId, RowExclusiveLock);
ScanKeyInit(&entry[0],