Skip to content

Commit 9a9825f

Browse files
committed
Remove heap_mark4update from AlterTableCreateToastTable. This has
never been the correct procedure for locking a relation, and the recently-found ALTER TABLE bug with adding a constraint and a toast table in the same command shows why it's a bad idea.
1 parent 6fe27ca commit 9a9825f

File tree

1 file changed

+15
-37
lines changed

1 file changed

+15
-37
lines changed

src/backend/commands/tablecmds.c

Lines changed: 15 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.39 2002/09/04 20:31:15 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.40 2002/09/06 00:01:53 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -3325,11 +3325,9 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
33253325
{
33263326
Relation rel;
33273327
HeapTuple reltup;
3328-
HeapTupleData classtuple;
33293328
TupleDesc tupdesc;
33303329
bool shared_relation;
33313330
Relation class_rel;
3332-
Buffer buffer;
33333331
Oid toast_relid;
33343332
Oid toast_idxid;
33353333
char toast_relname[NAMEDATALEN];
@@ -3366,42 +3364,14 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
33663364
if (shared_relation && IsUnderPostmaster)
33673365
elog(ERROR, "Shared relations cannot be toasted after initdb");
33683366

3369-
/*
3370-
* lock the pg_class tuple for update (is that really needed?)
3371-
*/
3372-
class_rel = heap_openr(RelationRelationName, RowExclusiveLock);
3373-
3374-
reltup = SearchSysCache(RELOID,
3375-
ObjectIdGetDatum(relOid),
3376-
0, 0, 0);
3377-
if (!HeapTupleIsValid(reltup))
3378-
elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
3379-
RelationGetRelationName(rel));
3380-
classtuple.t_self = reltup->t_self;
3381-
ReleaseSysCache(reltup);
3382-
3383-
switch (heap_mark4update(class_rel, &classtuple, &buffer,
3384-
GetCurrentCommandId()))
3385-
{
3386-
case HeapTupleSelfUpdated:
3387-
case HeapTupleMayBeUpdated:
3388-
break;
3389-
default:
3390-
elog(ERROR, "couldn't lock pg_class tuple");
3391-
}
3392-
reltup = heap_copytuple(&classtuple);
3393-
ReleaseBuffer(buffer);
3394-
33953367
/*
33963368
* Is it already toasted?
33973369
*/
3398-
if (((Form_pg_class) GETSTRUCT(reltup))->reltoastrelid != InvalidOid)
3370+
if (rel->rd_rel->reltoastrelid != InvalidOid)
33993371
{
34003372
if (silent)
34013373
{
34023374
heap_close(rel, NoLock);
3403-
heap_close(class_rel, NoLock);
3404-
heap_freetuple(reltup);
34053375
return;
34063376
}
34073377

@@ -3417,8 +3387,6 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
34173387
if (silent)
34183388
{
34193389
heap_close(rel, NoLock);
3420-
heap_close(class_rel, NoLock);
3421-
heap_freetuple(reltup);
34223390
return;
34233391
}
34243392

@@ -3509,8 +3477,17 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
35093477
setRelhasindex(toast_relid, true, true, toast_idxid);
35103478

35113479
/*
3512-
* Store the toast table's OID in the parent relation's tuple
3480+
* Store the toast table's OID in the parent relation's pg_class row
35133481
*/
3482+
class_rel = heap_openr(RelationRelationName, RowExclusiveLock);
3483+
3484+
reltup = SearchSysCacheCopy(RELOID,
3485+
ObjectIdGetDatum(relOid),
3486+
0, 0, 0);
3487+
if (!HeapTupleIsValid(reltup))
3488+
elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
3489+
RelationGetRelationName(rel));
3490+
35143491
((Form_pg_class) GETSTRUCT(reltup))->reltoastrelid = toast_relid;
35153492

35163493
simple_heap_update(class_rel, &reltup->t_self, reltup);
@@ -3520,6 +3497,8 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
35203497

35213498
heap_freetuple(reltup);
35223499

3500+
heap_close(class_rel, RowExclusiveLock);
3501+
35233502
/*
35243503
* Register dependency from the toast table to the master, so that the
35253504
* toast table will be deleted if the master is.
@@ -3534,9 +3513,8 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
35343513
recordDependencyOn(&toastobject, &baseobject, DEPENDENCY_INTERNAL);
35353514

35363515
/*
3537-
* Close relations and make changes visible
3516+
* Clean up and make changes visible
35383517
*/
3539-
heap_close(class_rel, NoLock);
35403518
heap_close(rel, NoLock);
35413519

35423520
CommandCounterIncrement();

0 commit comments

Comments
 (0)