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.
This commit is contained in:
parent
6fe27ca2fb
commit
9a9825f96a
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.39 2002/09/04 20:31:15 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.40 2002/09/06 00:01:53 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -3325,11 +3325,9 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
|
||||||
{
|
{
|
||||||
Relation rel;
|
Relation rel;
|
||||||
HeapTuple reltup;
|
HeapTuple reltup;
|
||||||
HeapTupleData classtuple;
|
|
||||||
TupleDesc tupdesc;
|
TupleDesc tupdesc;
|
||||||
bool shared_relation;
|
bool shared_relation;
|
||||||
Relation class_rel;
|
Relation class_rel;
|
||||||
Buffer buffer;
|
|
||||||
Oid toast_relid;
|
Oid toast_relid;
|
||||||
Oid toast_idxid;
|
Oid toast_idxid;
|
||||||
char toast_relname[NAMEDATALEN];
|
char toast_relname[NAMEDATALEN];
|
||||||
|
@ -3366,42 +3364,14 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
|
||||||
if (shared_relation && IsUnderPostmaster)
|
if (shared_relation && IsUnderPostmaster)
|
||||||
elog(ERROR, "Shared relations cannot be toasted after initdb");
|
elog(ERROR, "Shared relations cannot be toasted after initdb");
|
||||||
|
|
||||||
/*
|
|
||||||
* lock the pg_class tuple for update (is that really needed?)
|
|
||||||
*/
|
|
||||||
class_rel = heap_openr(RelationRelationName, RowExclusiveLock);
|
|
||||||
|
|
||||||
reltup = SearchSysCache(RELOID,
|
|
||||||
ObjectIdGetDatum(relOid),
|
|
||||||
0, 0, 0);
|
|
||||||
if (!HeapTupleIsValid(reltup))
|
|
||||||
elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
|
|
||||||
RelationGetRelationName(rel));
|
|
||||||
classtuple.t_self = reltup->t_self;
|
|
||||||
ReleaseSysCache(reltup);
|
|
||||||
|
|
||||||
switch (heap_mark4update(class_rel, &classtuple, &buffer,
|
|
||||||
GetCurrentCommandId()))
|
|
||||||
{
|
|
||||||
case HeapTupleSelfUpdated:
|
|
||||||
case HeapTupleMayBeUpdated:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
elog(ERROR, "couldn't lock pg_class tuple");
|
|
||||||
}
|
|
||||||
reltup = heap_copytuple(&classtuple);
|
|
||||||
ReleaseBuffer(buffer);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Is it already toasted?
|
* Is it already toasted?
|
||||||
*/
|
*/
|
||||||
if (((Form_pg_class) GETSTRUCT(reltup))->reltoastrelid != InvalidOid)
|
if (rel->rd_rel->reltoastrelid != InvalidOid)
|
||||||
{
|
{
|
||||||
if (silent)
|
if (silent)
|
||||||
{
|
{
|
||||||
heap_close(rel, NoLock);
|
heap_close(rel, NoLock);
|
||||||
heap_close(class_rel, NoLock);
|
|
||||||
heap_freetuple(reltup);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3417,8 +3387,6 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
|
||||||
if (silent)
|
if (silent)
|
||||||
{
|
{
|
||||||
heap_close(rel, NoLock);
|
heap_close(rel, NoLock);
|
||||||
heap_close(class_rel, NoLock);
|
|
||||||
heap_freetuple(reltup);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3509,8 +3477,17 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
|
||||||
setRelhasindex(toast_relid, true, true, toast_idxid);
|
setRelhasindex(toast_relid, true, true, toast_idxid);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Store the toast table's OID in the parent relation's tuple
|
* Store the toast table's OID in the parent relation's pg_class row
|
||||||
*/
|
*/
|
||||||
|
class_rel = heap_openr(RelationRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
|
reltup = SearchSysCacheCopy(RELOID,
|
||||||
|
ObjectIdGetDatum(relOid),
|
||||||
|
0, 0, 0);
|
||||||
|
if (!HeapTupleIsValid(reltup))
|
||||||
|
elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
|
||||||
|
RelationGetRelationName(rel));
|
||||||
|
|
||||||
((Form_pg_class) GETSTRUCT(reltup))->reltoastrelid = toast_relid;
|
((Form_pg_class) GETSTRUCT(reltup))->reltoastrelid = toast_relid;
|
||||||
|
|
||||||
simple_heap_update(class_rel, &reltup->t_self, reltup);
|
simple_heap_update(class_rel, &reltup->t_self, reltup);
|
||||||
|
@ -3520,6 +3497,8 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
|
||||||
|
|
||||||
heap_freetuple(reltup);
|
heap_freetuple(reltup);
|
||||||
|
|
||||||
|
heap_close(class_rel, RowExclusiveLock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register dependency from the toast table to the master, so that the
|
* Register dependency from the toast table to the master, so that the
|
||||||
* toast table will be deleted if the master is.
|
* toast table will be deleted if the master is.
|
||||||
|
@ -3534,9 +3513,8 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
|
||||||
recordDependencyOn(&toastobject, &baseobject, DEPENDENCY_INTERNAL);
|
recordDependencyOn(&toastobject, &baseobject, DEPENDENCY_INTERNAL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Close relations and make changes visible
|
* Clean up and make changes visible
|
||||||
*/
|
*/
|
||||||
heap_close(class_rel, NoLock);
|
|
||||||
heap_close(rel, NoLock);
|
heap_close(rel, NoLock);
|
||||||
|
|
||||||
CommandCounterIncrement();
|
CommandCounterIncrement();
|
||||||
|
|
Loading…
Reference in New Issue