aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/catalog/dependency.c31
-rw-r--r--src/backend/catalog/heap.c9
-rw-r--r--src/backend/catalog/namespace.c6
-rw-r--r--src/backend/catalog/pg_namespace.c15
-rw-r--r--src/backend/commands/schemacmds.c2
-rw-r--r--src/include/catalog/pg_namespace.h2
6 files changed, 51 insertions, 14 deletions
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index 0c91536c6c3..3187c9ca5e7 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -549,17 +549,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))
{
@@ -568,6 +572,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 2b77b84be01..384e90de7c5 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -945,10 +945,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
@@ -1222,6 +1224,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.
*/
@@ -1242,7 +1248,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 079a19379b6..b57c25595fc 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -3325,7 +3325,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();
}
@@ -3349,7 +3350,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 ceebac2f7e1..45762c25b9c 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 82bbf8fa506..671b17dba1f 100644
--- a/src/backend/commands/schemacmds.c
+++ b/src/backend/commands/schemacmds.c
@@ -95,7 +95,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 680802d7fea..a21b9750738 100644
--- a/src/include/catalog/pg_namespace.h
+++ b/src/include/catalog/pg_namespace.h
@@ -77,6 +77,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 */