Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit08dd23c

Browse files
committed
Fix some issues with temp/transient tables in extension scripts.
Phil Sorber reported that a rewriting ALTER TABLE within an extensionupdate script failed, because it creates and then drops a placeholdertable; the drop was being disallowed because the table was marked as anextension member. We could hack that specific case but it seems likelythat there might be related cases now or in the future, so the mostpractical solution seems to be to create an exception to the general rulethat extension member objects can only be dropped by dropping the owningextension. To wit: if the DROP is issued within the extension's owncreation or update scripts, we'll allow it, implicitly performing an"ALTER EXTENSION DROP object" first. This will simplify cases such asextension downgrade scripts anyway.No docs change since we don't seem to have documented the idea that youwould need ALTER EXTENSION DROP for such an action to begin with.Also, arrange for explicitly temporary tables to not get linked asextension members in the first place, and the same for the magicpg_temp_nnn schemas that are created to hold them. This prevents assortedunpleasant results if an extension script creates a temp table: the forceddrop at session end would either fail or remove the entire extension, andneither of those outcomes is desirable. Note that this doesn't fix theALTER TABLE scenario, since the placeholder table is not temp (unless thetable being rewritten is).Back-patch to 9.1.
1 parentc5e073c commit08dd23c

File tree

6 files changed

+51
-14
lines changed

6 files changed

+51
-14
lines changed

‎src/backend/catalog/dependency.c

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -560,17 +560,21 @@ findDependentObjects(const ObjectAddress *object,
560560
* another object, or is part of the extension that is the
561561
* other object. We have three cases:
562562
*
563-
* 1. At the outermost recursion level, disallow the DROP. (We
564-
* just ereport here, rather than proceeding, since no other
565-
* dependencies are likely to be interesting.)However, if
566-
* the owning object is listed in pendingObjects, just release
567-
* the caller's lock and return; we'll eventually complete the
568-
* DROP when we reach that entry in the pending list.
563+
* 1. At the outermost recursion level, we normally disallow
564+
* the DROP. (We just ereport here, rather than proceeding,
565+
* since no other dependencies are likely to be interesting.)
566+
* However, there are exceptions.
569567
*/
570568
if (stack==NULL)
571569
{
572570
char*otherObjDesc;
573571

572+
/*
573+
* Exception 1a: if the owning object is listed in
574+
* pendingObjects, just release the caller's lock and
575+
* return. We'll eventually complete the DROP when we
576+
* reach that entry in the pending list.
577+
*/
574578
if (pendingObjects&&
575579
object_address_present(&otherObject,pendingObjects))
576580
{
@@ -579,6 +583,21 @@ findDependentObjects(const ObjectAddress *object,
579583
ReleaseDeletionLock(object);
580584
return;
581585
}
586+
587+
/*
588+
* Exception 1b: if the owning object is the extension
589+
* currently being created/altered, it's okay to continue
590+
* with the deletion. This allows dropping of an
591+
* extension's objects within the extension's scripts,
592+
* as well as corner cases such as dropping a transient
593+
* object created within such a script.
594+
*/
595+
if (creating_extension&&
596+
otherObject.classId==ExtensionRelationId&&
597+
otherObject.objectId==CurrentExtensionObject)
598+
break;
599+
600+
/* No exception applies, so throw the error */
582601
otherObjDesc=getObjectDescription(&otherObject);
583602
ereport(ERROR,
584603
(errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),

‎src/backend/catalog/heap.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -957,10 +957,12 @@ AddNewRelationType(const char *typeName,
957957
*reltablespace: OID of tablespace it goes in
958958
*relid: OID to assign to new rel, or InvalidOid to select a new OID
959959
*reltypeid: OID to assign to rel's rowtype, or InvalidOid to select one
960+
*reloftypeid: if a typed table, OID of underlying type; else InvalidOid
960961
*ownerid: OID of new rel's owner
961962
*tupdesc: tuple descriptor (source of column definitions)
962963
*cooked_constraints: list of precooked check constraints and defaults
963964
*relkind: relkind for new rel
965+
*relpersistence: rel's persistence status (permanent, temp, or unlogged)
964966
*shared_relation: TRUE if it's to be a shared relation
965967
*mapped_relation: TRUE if the relation will use the relfilenode map
966968
*oidislocal: TRUE if oid column (if any) should be marked attislocal
@@ -1235,6 +1237,10 @@ heap_create_with_catalog(const char *relname,
12351237
* should they have any ACL entries. The same applies for extension
12361238
* dependencies.
12371239
*
1240+
* If it's a temp table, we do not make it an extension member; this
1241+
* prevents the unintuitive result that deletion of the temp table at
1242+
* session end would make the whole extension go away.
1243+
*
12381244
* Also, skip this in bootstrap mode, since we don't make dependencies
12391245
* while bootstrapping.
12401246
*/
@@ -1255,7 +1261,8 @@ heap_create_with_catalog(const char *relname,
12551261

12561262
recordDependencyOnOwner(RelationRelationId,relid,ownerid);
12571263

1258-
recordDependencyOnCurrentExtension(&myself, false);
1264+
if (relpersistence!=RELPERSISTENCE_TEMP)
1265+
recordDependencyOnCurrentExtension(&myself, false);
12591266

12601267
if (reloftypeid)
12611268
{

‎src/backend/catalog/namespace.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3558,7 +3558,8 @@ InitTempTableNamespace(void)
35583558
* temp tables. This works because the places that access the temp
35593559
* namespace for my own backend skip permissions checks on it.
35603560
*/
3561-
namespaceId=NamespaceCreate(namespaceName,BOOTSTRAP_SUPERUSERID);
3561+
namespaceId=NamespaceCreate(namespaceName,BOOTSTRAP_SUPERUSERID,
3562+
true);
35623563
/* Advance command counter to make namespace visible */
35633564
CommandCounterIncrement();
35643565
}
@@ -3582,7 +3583,8 @@ InitTempTableNamespace(void)
35823583
toastspaceId=get_namespace_oid(namespaceName, true);
35833584
if (!OidIsValid(toastspaceId))
35843585
{
3585-
toastspaceId=NamespaceCreate(namespaceName,BOOTSTRAP_SUPERUSERID);
3586+
toastspaceId=NamespaceCreate(namespaceName,BOOTSTRAP_SUPERUSERID,
3587+
true);
35863588
/* Advance command counter to make namespace visible */
35873589
CommandCounterIncrement();
35883590
}

‎src/backend/catalog/pg_namespace.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,18 @@
2626

2727
/* ----------------
2828
* NamespaceCreate
29+
*
30+
* Create a namespace (schema) with the given name and owner OID.
31+
*
32+
* If isTemp is true, this schema is a per-backend schema for holding
33+
* temporary tables. Currently, the only effect of that is to prevent it
34+
* from being linked as a member of any active extension. (If someone
35+
* does CREATE TEMP TABLE in an extension script, we don't want the temp
36+
* schema to become part of the extension.)
2937
* ---------------
3038
*/
3139
Oid
32-
NamespaceCreate(constchar*nspName,OidownerId)
40+
NamespaceCreate(constchar*nspName,OidownerId,boolisTemp)
3341
{
3442
Relationnspdesc;
3543
HeapTupletup;
@@ -82,8 +90,9 @@ NamespaceCreate(const char *nspName, Oid ownerId)
8290
/* dependency on owner */
8391
recordDependencyOnOwner(NamespaceRelationId,nspoid,ownerId);
8492

85-
/* dependency on extension */
86-
recordDependencyOnCurrentExtension(&myself, false);
93+
/* dependency on extension ... but not for magic temp schemas */
94+
if (!isTemp)
95+
recordDependencyOnCurrentExtension(&myself, false);
8796

8897
/* Post creation hook for new schema */
8998
InvokeObjectAccessHook(OAT_POST_CREATE,NamespaceRelationId,nspoid,0);

‎src/backend/commands/schemacmds.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString)
9494
save_sec_context |SECURITY_LOCAL_USERID_CHANGE);
9595

9696
/* Create the schema's namespace */
97-
namespaceId=NamespaceCreate(schemaName,owner_uid);
97+
namespaceId=NamespaceCreate(schemaName,owner_uid, false);
9898

9999
/* Advance cmd counter to make the namespace visible */
100100
CommandCounterIncrement();

‎src/include/catalog/pg_namespace.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,6 @@ DESCR("standard public schema");
7979
/*
8080
* prototypes for functions in pg_namespace.c
8181
*/
82-
externOidNamespaceCreate(constchar*nspName,OidownerId);
82+
externOidNamespaceCreate(constchar*nspName,OidownerId,boolisTemp);
8383

8484
#endif/* PG_NAMESPACE_H */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp