Skip to content

Commit 0360c53

Browse files
committed
Fix ALTER COLUMN TYPE to not open a relation without any lock.
If the column being modified is referenced by a foreign key constraint of another table, ALTER TABLE would open the other table (to re-parse the constraint's definition) without having first obtained a lock on it. This was evidently intentional, but that doesn't mean it's really safe. It's especially not safe in 9.3, which pre-dates use of MVCC scans for catalog reads, but even in current releases it doesn't seem like a good idea. We know we'll need AccessExclusiveLock shortly to drop the obsoleted constraint, so just get that a little sooner to close the hole. Per testing with a patch that complains if we open a relation without holding any lock on it. I don't plan to back-patch that patch, but we should close the holes it identifies in all supported branches. Discussion: https://postgr.es/m/2038.1538335244@sss.pgh.pa.us
1 parent 2855421 commit 0360c53

File tree

1 file changed

+12
-2
lines changed

1 file changed

+12
-2
lines changed

src/backend/commands/tablecmds.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8686,8 +8686,7 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode)
86868686
* appropriate work queue entries. We do this before dropping because in
86878687
* the case of a FOREIGN KEY constraint, we might not yet have exclusive
86888688
* lock on the table the constraint is attached to, and we need to get
8689-
* that before dropping. It's safe because the parser won't actually look
8690-
* at the catalogs to detect the existing entry.
8689+
* that before reparsing/dropping.
86918690
*
86928691
* We can't rely on the output of deparsing to tell us which relation to
86938692
* operate on, because concurrent activity might have made the name
@@ -8703,6 +8702,7 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode)
87038702
Form_pg_constraint con;
87048703
Oid relid;
87058704
Oid confrelid;
8705+
char contype;
87068706
bool conislocal;
87078707

87088708
tup = SearchSysCache1(CONSTROID, ObjectIdGetDatum(oldId));
@@ -8711,6 +8711,7 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode)
87118711
con = (Form_pg_constraint) GETSTRUCT(tup);
87128712
relid = con->conrelid;
87138713
confrelid = con->confrelid;
8714+
contype = con->contype;
87148715
conislocal = con->conislocal;
87158716
ReleaseSysCache(tup);
87168717

@@ -8723,6 +8724,15 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode)
87238724
if (!conislocal)
87248725
continue;
87258726

8727+
/*
8728+
* When rebuilding an FK constraint that references the table we're
8729+
* modifying, we might not yet have any lock on the FK's table, so get
8730+
* one now. We'll need AccessExclusiveLock for the DROP CONSTRAINT
8731+
* step, so there's no value in asking for anything weaker.
8732+
*/
8733+
if (relid != tab->relid && contype == CONSTRAINT_FOREIGN)
8734+
LockRelationOid(relid, AccessExclusiveLock);
8735+
87268736
ATPostAlterTypeParse(oldId, relid, confrelid,
87278737
(char *) lfirst(def_item),
87288738
wqueue, lockmode, tab->rewrite);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy