summaryrefslogtreecommitdiff
path: root/src/backend/commands
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 /src/backend/commands
parent8ab9df0db196b6e1afa75838394eb27e9955e80e (diff)
downloadpostgresql-ec3e183ec51bb2d4032be6d5402ddc7b4c8acb71.tar.gz
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.
Diffstat (limited to 'src/backend/commands')
-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 024d4c8a00..63b3ffa4ef 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],