diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index db86262b4f06ec5b78f834eb10fbae45a1e77033..eca064f0cdef7ee6367b76a4da785e29a9cfdbc6 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -560,17 +560,21 @@ findDependentObjects(const ObjectAddress *object,
 				 * another object, or is part of the extension that is the
 				 * other object.  We have three cases:
 				 *
-				 * 1. At the outermost recursion level, disallow the DROP. (We
-				 * just ereport here, rather than proceeding, since no other
-				 * dependencies are likely to be interesting.)	However, if
-				 * the owning object is listed in pendingObjects, just release
-				 * the caller's lock and return; we'll eventually complete the
-				 * DROP when we reach that entry in the pending list.
+				 * 1. At the outermost recursion level, we normally disallow
+				 * the DROP.  (We just ereport here, rather than proceeding,
+				 * since no other dependencies are likely to be interesting.)
+				 * However, there are exceptions.
 				 */
 				if (stack == NULL)
 				{
 					char	   *otherObjDesc;
 
+					/*
+					 * Exception 1a: if the owning object is listed in
+					 * pendingObjects, just release the caller's lock and
+					 * return.  We'll eventually complete the DROP when we
+					 * reach that entry in the pending list.
+					 */
 					if (pendingObjects &&
 						object_address_present(&otherObject, pendingObjects))
 					{
@@ -579,6 +583,21 @@ findDependentObjects(const ObjectAddress *object,
 						ReleaseDeletionLock(object);
 						return;
 					}
+
+					/*
+					 * Exception 1b: if the owning object is the extension
+					 * currently being created/altered, it's okay to continue
+					 * with the deletion.  This allows dropping of an
+					 * extension's objects within the extension's scripts,
+					 * as well as corner cases such as dropping a transient
+					 * object created within such a script.
+					 */
+					if (creating_extension &&
+						otherObject.classId == ExtensionRelationId &&
+						otherObject.objectId == CurrentExtensionObject)
+						break;
+
+					/* No exception applies, so throw the error */
 					otherObjDesc = getObjectDescription(&otherObject);
 					ereport(ERROR,
 							(errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index a8653cd49562d95748c8fe38517aa1d0785c9aff..d1d458d7fa485606f1c0e877fdd558b42f6ea273 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -957,10 +957,12 @@ AddNewRelationType(const char *typeName,
  *	reltablespace: OID of tablespace it goes in
  *	relid: OID to assign to new rel, or InvalidOid to select a new OID
  *	reltypeid: OID to assign to rel's rowtype, or InvalidOid to select one
+ *	reloftypeid: if a typed table, OID of underlying type; else InvalidOid
  *	ownerid: OID of new rel's owner
  *	tupdesc: tuple descriptor (source of column definitions)
  *	cooked_constraints: list of precooked check constraints and defaults
  *	relkind: relkind for new rel
+ *	relpersistence: rel's persistence status (permanent, temp, or unlogged)
  *	shared_relation: TRUE if it's to be a shared relation
  *	mapped_relation: TRUE if the relation will use the relfilenode map
  *	oidislocal: TRUE if oid column (if any) should be marked attislocal
@@ -1235,6 +1237,10 @@ heap_create_with_catalog(const char *relname,
 	 * should they have any ACL entries.  The same applies for extension
 	 * dependencies.
 	 *
+	 * If it's a temp table, we do not make it an extension member; this
+	 * prevents the unintuitive result that deletion of the temp table at
+	 * session end would make the whole extension go away.
+	 *
 	 * Also, skip this in bootstrap mode, since we don't make dependencies
 	 * while bootstrapping.
 	 */
@@ -1255,7 +1261,8 @@ heap_create_with_catalog(const char *relname,
 
 		recordDependencyOnOwner(RelationRelationId, relid, ownerid);
 
-		recordDependencyOnCurrentExtension(&myself, false);
+		if (relpersistence != RELPERSISTENCE_TEMP)
+			recordDependencyOnCurrentExtension(&myself, false);
 
 		if (reloftypeid)
 		{
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 80d6fc7d0c2c721b43751cfe0d1d7233796f7d31..dc8f8eaf3f3f60f51fd8b59aa78ccfc36e1b23f9 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -3558,7 +3558,8 @@ InitTempTableNamespace(void)
 		 * temp tables.  This works because the places that access the temp
 		 * namespace for my own backend skip permissions checks on it.
 		 */
-		namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID);
+		namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
+									  true);
 		/* Advance command counter to make namespace visible */
 		CommandCounterIncrement();
 	}
@@ -3582,7 +3583,8 @@ InitTempTableNamespace(void)
 	toastspaceId = get_namespace_oid(namespaceName, true);
 	if (!OidIsValid(toastspaceId))
 	{
-		toastspaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID);
+		toastspaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID,
+									   true);
 		/* Advance command counter to make namespace visible */
 		CommandCounterIncrement();
 	}
diff --git a/src/backend/catalog/pg_namespace.c b/src/backend/catalog/pg_namespace.c
index d5ab48a59dc76eb1eff7e6ad4229e87693ba00c2..be812a246c09dbc92f762fb50f1a6fac0e074f73 100644
--- a/src/backend/catalog/pg_namespace.c
+++ b/src/backend/catalog/pg_namespace.c
@@ -26,10 +26,18 @@
 
 /* ----------------
  * NamespaceCreate
+ *
+ * Create a namespace (schema) with the given name and owner OID.
+ *
+ * If isTemp is true, this schema is a per-backend schema for holding
+ * temporary tables.  Currently, the only effect of that is to prevent it
+ * from being linked as a member of any active extension.  (If someone
+ * does CREATE TEMP TABLE in an extension script, we don't want the temp
+ * schema to become part of the extension.)
  * ---------------
  */
 Oid
-NamespaceCreate(const char *nspName, Oid ownerId)
+NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp)
 {
 	Relation	nspdesc;
 	HeapTuple	tup;
@@ -82,8 +90,9 @@ NamespaceCreate(const char *nspName, Oid ownerId)
 	/* dependency on owner */
 	recordDependencyOnOwner(NamespaceRelationId, nspoid, ownerId);
 
-	/* dependency on extension */
-	recordDependencyOnCurrentExtension(&myself, false);
+	/* dependency on extension ... but not for magic temp schemas */
+	if (!isTemp)
+		recordDependencyOnCurrentExtension(&myself, false);
 
 	/* Post creation hook for new schema */
 	InvokeObjectAccessHook(OAT_POST_CREATE, NamespaceRelationId, nspoid, 0);
diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c
index 916328529a071d94b668f7b789a15cb179e631e4..6745af501d4680ad08d5945cb289a1af3716afb3 100644
--- a/src/backend/commands/schemacmds.c
+++ b/src/backend/commands/schemacmds.c
@@ -94,7 +94,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString)
 							save_sec_context | SECURITY_LOCAL_USERID_CHANGE);
 
 	/* Create the schema's namespace */
-	namespaceId = NamespaceCreate(schemaName, owner_uid);
+	namespaceId = NamespaceCreate(schemaName, owner_uid, false);
 
 	/* Advance cmd counter to make the namespace visible */
 	CommandCounterIncrement();
diff --git a/src/include/catalog/pg_namespace.h b/src/include/catalog/pg_namespace.h
index aad76a1452aae126c468553bec752182a980ff12..1daba477b409a453bfbe19885fd57455c56245cc 100644
--- a/src/include/catalog/pg_namespace.h
+++ b/src/include/catalog/pg_namespace.h
@@ -79,6 +79,6 @@ DESCR("standard public schema");
 /*
  * prototypes for functions in pg_namespace.c
  */
-extern Oid	NamespaceCreate(const char *nspName, Oid ownerId);
+extern Oid	NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp);
 
 #endif   /* PG_NAMESPACE_H */