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

Commit6b71c92

Browse files
committed
Prevent ALTER TYPE/DOMAIN/OPERATOR from changing extension membership.
If recordDependencyOnCurrentExtension is invoked on a pre-existing,free-standing object during an extension update script, that objectwill become owned by the extension. In our current code this ispossible in three cases:* Replacing a "shell" type or operator.* CREATE OR REPLACE overwriting an existing object.* ALTER TYPE SET, ALTER DOMAIN SET, and ALTER OPERATOR SET.The first of these cases is intentional behavior, as noted by theexisting comments for GenerateTypeDependencies. It seems likeappropriate behavior for CREATE OR REPLACE too; at least, the obviousalternatives are not better. However, the fact that it happens duringALTER is an artifact of trying to share code (GenerateTypeDependenciesand makeOperatorDependencies) between the CREATE and ALTER cases.Since an extension script would be unlikely to ALTER an object thatdidn't already belong to the extension, this behavior is not verytroubling for the direct target object ... but ALTER TYPE SET willrecurse to dependent domains, and it is very uncool for those tobecome owned by the extension if they were not already.Let's fix this by redefining the ALTER cases to never change extensionmembership, full stop. We could minimize the behavioral change byonly changing the behavior when ALTER TYPE SET is recursing to adomain, but that would complicate the code and it does not seem likea better definition.Per bug #17144 from Alex Kozhemyakin. Back-patch to v13 where ALTERTYPE SET was added. (The other cases are older, but since they onlyaffect the directly-named object, there's not enough of a problem tojustify changing the behavior further back.)Discussion:https://postgr.es/m/17144-e67d7a8f049de9af@postgresql.org
1 parentb66336c commit6b71c92

File tree

7 files changed

+41
-14
lines changed

7 files changed

+41
-14
lines changed

‎src/backend/catalog/pg_depend.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,13 @@ recordMultipleDependencies(const ObjectAddress *depender,
179179
* existed), so we must check for a pre-existing extension membership entry.
180180
* Passing false is a guarantee that the object is newly created, and so
181181
* could not already be a member of any extension.
182+
*
183+
* Note: isReplace = true is typically used when updating a object in
184+
* CREATE OR REPLACE and similar commands. The net effect is that if an
185+
* extension script uses such a command on a pre-existing free-standing
186+
* object, the object will be absorbed into the extension. If the object
187+
* is already a member of some other extension, the command will fail.
188+
* This behavior is desirable for cases such as replacing a shell type.
182189
*/
183190
void
184191
recordDependencyOnCurrentExtension(constObjectAddress*object,

‎src/backend/catalog/pg_operator.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ OperatorShellMake(const char *operatorName,
268268
CatalogTupleInsert(pg_operator_desc,tup);
269269

270270
/* Add dependencies for the entry */
271-
makeOperatorDependencies(tup, false);
271+
makeOperatorDependencies(tup,true,false);
272272

273273
heap_freetuple(tup);
274274

@@ -546,7 +546,7 @@ OperatorCreate(const char *operatorName,
546546
}
547547

548548
/* Add dependencies for the entry */
549-
address=makeOperatorDependencies(tup,isUpdate);
549+
address=makeOperatorDependencies(tup,true,isUpdate);
550550

551551
/* Post creation hook for new operator */
552552
InvokeObjectPostCreateHook(OperatorRelationId,operatorObjectId,0);
@@ -766,11 +766,17 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId, bool isDelete)
766766
* complete operator, a new shell operator, a just-updated shell,
767767
* or an operator that's being modified by ALTER OPERATOR).
768768
*
769+
* makeExtensionDep should be true when making a new operator or
770+
* replacing a shell, false for ALTER OPERATOR. Passing false
771+
* will prevent any change in the operator's extension membership.
772+
*
769773
* NB: the OidIsValid tests in this routine are necessary, in case
770774
* the given operator is a shell.
771775
*/
772776
ObjectAddress
773-
makeOperatorDependencies(HeapTupletuple,boolisUpdate)
777+
makeOperatorDependencies(HeapTupletuple,
778+
boolmakeExtensionDep,
779+
boolisUpdate)
774780
{
775781
Form_pg_operatoroper= (Form_pg_operator)GETSTRUCT(tuple);
776782
ObjectAddressmyself,
@@ -857,7 +863,8 @@ makeOperatorDependencies(HeapTuple tuple, bool isUpdate)
857863
oper->oprowner);
858864

859865
/* Dependency on extension */
860-
recordDependencyOnCurrentExtension(&myself, true);
866+
if (makeExtensionDep)
867+
recordDependencyOnCurrentExtension(&myself, true);
861868

862869
returnmyself;
863870
}

‎src/backend/catalog/pg_type.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId)
167167
0,
168168
false,
169169
false,
170+
true,/* make extension dependency */
170171
false);
171172

172173
/* Post creation hook for new shell type */
@@ -504,6 +505,7 @@ TypeCreate(Oid newTypeOid,
504505
relationKind,
505506
isImplicitArray,
506507
isDependentType,
508+
true,/* make extension dependency */
507509
rebuildDeps);
508510

509511
/* Post creation hook for new type */
@@ -537,13 +539,17 @@ TypeCreate(Oid newTypeOid,
537539
* isDependentType is true if this is an implicit array or relation rowtype;
538540
* that means it doesn't need its own dependencies on owner etc.
539541
*
540-
* If rebuild is true, we remove existing dependencies and rebuild them
541-
* from scratch. This is needed for ALTER TYPE, and also when replacing
542-
* a shell type. We don't remove an existing extension dependency, though.
543-
* (That means an extension can't absorb a shell type created in another
544-
* extension, nor ALTER a type created by another extension. Also, if it
545-
* replaces a free-standing shell type or ALTERs a free-standing type,
546-
* that type will become a member of the extension.)
542+
* We make an extension-membership dependency if we're in an extension
543+
* script and makeExtensionDep is true (and isDependentType isn't true).
544+
* makeExtensionDep should be true when creating a new type or replacing a
545+
* shell type, but not for ALTER TYPE on an existing type. Passing false
546+
* causes the type's extension membership to be left alone.
547+
*
548+
* rebuild should be true if this is a pre-existing type. We will remove
549+
* existing dependencies and rebuild them from scratch. This is needed for
550+
* ALTER TYPE, and also when replacing a shell type. We don't remove any
551+
* existing extension dependency, though (hence, if makeExtensionDep is also
552+
* true and the type belongs to some other extension, an error will occur).
547553
*/
548554
void
549555
GenerateTypeDependencies(HeapTupletypeTuple,
@@ -553,6 +559,7 @@ GenerateTypeDependencies(HeapTuple typeTuple,
553559
charrelationKind,/* only for relation rowtypes */
554560
boolisImplicitArray,
555561
boolisDependentType,
562+
boolmakeExtensionDep,
556563
boolrebuild)
557564
{
558565
Form_pg_typetypeForm= (Form_pg_type)GETSTRUCT(typeTuple);
@@ -611,7 +618,8 @@ GenerateTypeDependencies(HeapTuple typeTuple,
611618
recordDependencyOnNewAcl(TypeRelationId,typeObjectId,0,
612619
typeForm->typowner,typacl);
613620

614-
recordDependencyOnCurrentExtension(&myself,rebuild);
621+
if (makeExtensionDep)
622+
recordDependencyOnCurrentExtension(&myself,rebuild);
615623
}
616624

617625
/* Normal dependencies on the I/O and support functions */

‎src/backend/commands/operatorcmds.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,7 @@ AlterOperator(AlterOperatorStmt *stmt)
542542

543543
CatalogTupleUpdate(catalog,&tup->t_self,tup);
544544

545-
address=makeOperatorDependencies(tup, true);
545+
address=makeOperatorDependencies(tup,false,true);
546546

547547
InvokeObjectPostAlterHook(OperatorRelationId,oprId,0);
548548

‎src/backend/commands/typecmds.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2675,6 +2675,7 @@ AlterDomainDefault(List *names, Node *defaultRaw)
26752675
0,/* relation kind is n/a */
26762676
false,/* a domain isn't an implicit array */
26772677
false,/* nor is it any kind of dependent type */
2678+
false,/* don't touch extension membership */
26782679
true);/* We do need to rebuild dependencies */
26792680

26802681
InvokeObjectPostAlterHook(TypeRelationId,domainoid,0);
@@ -4415,6 +4416,7 @@ AlterTypeRecurse(Oid typeOid, bool isImplicitArray,
44154416
0,/* we rejected composite types above */
44164417
isImplicitArray,/* it might be an array */
44174418
isImplicitArray,/* dependent iff it's array */
4419+
false,/* don't touch extension membership */
44184420
true);
44194421

44204422
InvokeObjectPostAlterHook(TypeRelationId,typeOid,0);

‎src/include/catalog/pg_operator.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,9 @@ extern ObjectAddress OperatorCreate(const char *operatorName,
9898
boolcanMerge,
9999
boolcanHash);
100100

101-
externObjectAddressmakeOperatorDependencies(HeapTupletuple,boolisUpdate);
101+
externObjectAddressmakeOperatorDependencies(HeapTupletuple,
102+
boolmakeExtensionDep,
103+
boolisUpdate);
102104

103105
externvoidOperatorUpd(OidbaseId,OidcommId,OidnegId,boolisDelete);
104106

‎src/include/catalog/pg_type.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ extern void GenerateTypeDependencies(HeapTuple typeTuple,
386386
* rowtypes */
387387
boolisImplicitArray,
388388
boolisDependentType,
389+
boolmakeExtensionDep,
389390
boolrebuild);
390391

391392
externvoidRenameTypeInternal(OidtypeOid,constchar*newTypeName,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp