summaryrefslogtreecommitdiff
path: root/src/backend/catalog
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>1999-09-18 19:08:25 +0000
committerTom Lane <tgl@sss.pgh.pa.us>1999-09-18 19:08:25 +0000
commitbd272cace63effa23d68a6b344a07e326b6a41e2 (patch)
tree3026c545c238bd38eadc7fb1fac89d636cf51673 /src/backend/catalog
parent6c86fd5ba49bc03949ea1c788023f39da9c0b9fe (diff)
downloadpostgresql-bd272cace63effa23d68a6b344a07e326b6a41e2.tar.gz
Mega-commit to make heap_open/heap_openr/heap_close take an
additional argument specifying the kind of lock to acquire/release (or 'NoLock' to do no lock processing). Ensure that all relations are locked with some appropriate lock level before being examined --- this ensures that relevant shared-inval messages have been processed and should prevent problems caused by concurrent VACUUM. Fix several bugs having to do with mismatched increment/decrement of relation ref count and mismatched heap_open/close (which amounts to the same thing). A bogus ref count on a relation doesn't matter much *unless* a SI Inval message happens to arrive at the wrong time, which is probably why we got away with this sloppiness for so long. Repair missing grab of AccessExclusiveLock in DROP TABLE, ALTER/RENAME TABLE, etc, as noted by Hiroshi. Recommend 'make clean all' after pulling this update; I modified the Relation struct layout slightly. Will post further discussion to pghackers list shortly.
Diffstat (limited to 'src/backend/catalog')
-rw-r--r--src/backend/catalog/aclchk.c69
-rw-r--r--src/backend/catalog/heap.c132
-rw-r--r--src/backend/catalog/index.c116
-rw-r--r--src/backend/catalog/indexing.c6
-rw-r--r--src/backend/catalog/pg_aggregate.c34
-rw-r--r--src/backend/catalog/pg_operator.c21
-rw-r--r--src/backend/catalog/pg_proc.c6
-rw-r--r--src/backend/catalog/pg_type.c31
8 files changed, 188 insertions, 227 deletions
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index 186ecd07f3..33a589ec88 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.27 1999/07/30 18:09:44 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.28 1999/09/18 19:06:33 tgl Exp $
*
* NOTES
* See acl.h.
@@ -105,19 +105,15 @@ ChangeAcl(char *relname,
* We can't use the syscache here, since we need to do a heap_replace on
* the tuple we find.
*/
- relation = heap_openr(RelationRelationName);
- if (!RelationIsValid(relation))
- elog(ERROR, "ChangeAcl: could not open '%s'??",
- RelationRelationName);
+ relation = heap_openr(RelationRelationName, RowExclusiveLock);
tuple = SearchSysCacheTuple(RELNAME,
PointerGetDatum(relname),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
{
- heap_close(relation);
+ heap_close(relation, RowExclusiveLock);
elog(ERROR, "ChangeAcl: class \"%s\" not found",
relname);
- return;
}
if (!heap_attisnull(tuple, Anum_pg_class_relacl))
@@ -164,7 +160,7 @@ ChangeAcl(char *relname,
CatalogIndexInsert(idescs, Num_pg_class_indices, relation, tuple);
CatalogCloseIndices(Num_pg_class_indices, idescs);
- heap_close(relation);
+ heap_close(relation, RowExclusiveLock);
if (free_old_acl)
pfree(old_acl);
pfree(new_acl);
@@ -213,13 +209,7 @@ in_group(AclId uid, AclId gid)
AclId *aidp;
int32 found = 0;
- relation = heap_openr(GroupRelationName);
- if (!RelationIsValid(relation))
- {
- elog(NOTICE, "in_group: could not open \"%s\"??",
- GroupRelationName);
- return 0;
- }
+ relation = heap_openr(GroupRelationName, RowExclusiveLock);
tuple = SearchSysCacheTuple(GROSYSID,
ObjectIdGetDatum(gid),
0, 0, 0);
@@ -242,7 +232,7 @@ in_group(AclId uid, AclId gid)
}
else
elog(NOTICE, "in_group: group %d not found", gid);
- heap_close(relation);
+ heap_close(relation, RowExclusiveLock);
return found;
}
@@ -413,6 +403,7 @@ pg_aclcheck(char *relname, char *usename, AclMode mode)
}
#ifndef ACLDEBUG
+ relation = heap_openr(RelationRelationName, RowExclusiveLock);
tuple = SearchSysCacheTuple(RELNAME,
PointerGetDatum(relname),
0, 0, 0);
@@ -420,18 +411,15 @@ pg_aclcheck(char *relname, char *usename, AclMode mode)
{
elog(ERROR, "pg_aclcheck: class \"%s\" not found",
relname);
- /* an elog(ERROR) kills us, so no need to return anything. */
}
if (!heap_attisnull(tuple, Anum_pg_class_relacl))
{
- relation = heap_openr(RelationRelationName);
tmp = (Acl *) heap_getattr(tuple,
Anum_pg_class_relacl,
RelationGetDescr(relation),
(bool *) NULL);
acl = makeacl(ACL_NUM(tmp));
memmove((char *) acl, (char *) tmp, ACL_SIZE(tmp));
- heap_close(relation);
}
else
{
@@ -442,42 +430,29 @@ pg_aclcheck(char *relname, char *usename, AclMode mode)
*/
int4 ownerId;
- relation = heap_openr(RelationRelationName);
ownerId = (int4) heap_getattr(tuple,
Anum_pg_class_relowner,
RelationGetDescr(relation),
(bool *) NULL);
acl = aclownerdefault(relname, (AclId) ownerId);
- heap_close(relation);
}
+ heap_close(relation, RowExclusiveLock);
#else
- { /* This is why the syscache is great... */
- static ScanKeyData relkey[1] = {
- {0, Anum_pg_class_relname, F_NAMEEQ}
- };
-
- relation = heap_openr(RelationRelationName);
- if (!RelationIsValid(relation))
- {
- elog(NOTICE, "pg_checkacl: could not open \"%-.*s\"??",
- RelationRelationName);
- return ACLCHECK_NO_CLASS;
- }
- tuple = SearchSysCacheTuple(RELNAME,
- PointerGetDatum(relname),
- 0, 0, 0);
- if (HeapTupleIsValid(tuple) &&
- !heap_attisnull(tuple, Anum_pg_class_relacl))
- {
- tmp = (Acl *) heap_getattr(tuple,
- Anum_pg_class_relacl,
- RelationGetDescr(relation),
- (bool *) NULL);
- acl = makeacl(ACL_NUM(tmp));
- memmove((char *) acl, (char *) tmp, ACL_SIZE(tmp));
- }
- heap_close(relation);
+ relation = heap_openr(RelationRelationName, RowExclusiveLock);
+ tuple = SearchSysCacheTuple(RELNAME,
+ PointerGetDatum(relname),
+ 0, 0, 0);
+ if (HeapTupleIsValid(tuple) &&
+ !heap_attisnull(tuple, Anum_pg_class_relacl))
+ {
+ tmp = (Acl *) heap_getattr(tuple,
+ Anum_pg_class_relacl,
+ RelationGetDescr(relation),
+ (bool *) NULL);
+ acl = makeacl(ACL_NUM(tmp));
+ memmove((char *) acl, (char *) tmp, ACL_SIZE(tmp));
}
+ heap_close(relation, RowExclusiveLock);
#endif
result = aclcheck(relname, acl, id, (AclIdType) ACL_IDTYPE_UID, mode);
if (acl)
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 561cb21a41..644f03eba8 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.95 1999/09/05 17:43:47 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.96 1999/09/18 19:06:33 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -243,8 +243,6 @@ heap_create(char *relname,
/* ----------------
* allocate a new relation descriptor.
- *
- * XXX the length computation may be incorrect, handle elsewhere
* ----------------
*/
len = sizeof(RelationData);
@@ -474,7 +472,7 @@ RelnameFindRelid(char *relname)
ScanKeyData key;
HeapScanDesc pg_class_scan;
- pg_class_desc = heap_openr(RelationRelationName);
+ pg_class_desc = heap_openr(RelationRelationName, AccessShareLock);
/* ----------------
* At bootstrap time, we have to do this the hard way. Form the
@@ -511,7 +509,7 @@ RelnameFindRelid(char *relname)
heap_endscan(pg_class_scan);
- heap_close(pg_class_desc);
+ heap_close(pg_class_desc, AccessShareLock);
}
return relid;
}
@@ -539,14 +537,12 @@ AddNewAttributeTuples(Oid new_rel_oid,
* open pg_attribute
* ----------------
*/
- rel = heap_openr(AttributeRelationName);
+ rel = heap_openr(AttributeRelationName, RowExclusiveLock);
/* -----------------
* Check if we have any indices defined on pg_attribute.
* -----------------
*/
- Assert(rel);
- Assert(rel->rd_rel);
hasindex = RelationGetForm(rel)->relhasindex;
if (hasindex)
CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs);
@@ -607,7 +603,7 @@ AddNewAttributeTuples(Oid new_rel_oid,
dpp++;
}
- heap_close(rel);
+ heap_close(rel, RowExclusiveLock);
/*
* close pg_attribute indices
@@ -829,7 +825,7 @@ heap_create_with_catalog(char *relname,
* now update the information in pg_class.
* ----------------
*/
- pg_class_desc = heap_openr(RelationRelationName);
+ pg_class_desc = heap_openr(RelationRelationName, RowExclusiveLock);
AddNewRelationTuple(pg_class_desc,
new_rel_desc,
@@ -853,8 +849,8 @@ heap_create_with_catalog(char *relname,
* SOMEDAY: fill the STATISTIC relation properly.
* ----------------
*/
- heap_close(new_rel_desc);
- heap_close(pg_class_desc);
+ heap_close(new_rel_desc, NoLock); /* do not unlock till end of xact */
+ heap_close(pg_class_desc, RowExclusiveLock);
return new_rel_oid;
}
@@ -913,7 +909,7 @@ RelationRemoveInheritance(Relation relation)
* open pg_inherits
* ----------------
*/
- catalogRelation = heap_openr(InheritsRelationName);
+ catalogRelation = heap_openr(InheritsRelationName, RowExclusiveLock);
/* ----------------
* form a scan key for the subclasses of this class
@@ -937,13 +933,15 @@ RelationRemoveInheritance(Relation relation)
tuple = heap_getnext(scan, 0);
if (HeapTupleIsValid(tuple))
{
+ Oid subclass = ((Form_pg_inherits) GETSTRUCT(tuple))->inhrel;
+
heap_endscan(scan);
- heap_close(catalogRelation);
+ heap_close(catalogRelation, RowExclusiveLock);
elog(ERROR, "Relation '%u' inherits '%s'",
- ((Form_pg_inherits) GETSTRUCT(tuple))->inhrel,
- RelationGetRelationName(relation));
+ subclass, RelationGetRelationName(relation));
}
+ heap_endscan(scan);
/* ----------------
* If we get here, it means the relation has no subclasses
@@ -965,13 +963,14 @@ RelationRemoveInheritance(Relation relation)
}
heap_endscan(scan);
- heap_close(catalogRelation);
+ heap_close(catalogRelation, RowExclusiveLock);
/* ----------------
* now remove dead IPL tuples
* ----------------
*/
- catalogRelation = heap_openr(InheritancePrecidenceListRelationName);
+ catalogRelation = heap_openr(InheritancePrecidenceListRelationName,
+ RowExclusiveLock);
entry.sk_attno = Anum_pg_ipl_iplrel;
@@ -985,7 +984,7 @@ RelationRemoveInheritance(Relation relation)
heap_delete(catalogRelation, &tuple->t_self, NULL);
heap_endscan(scan);
- heap_close(catalogRelation);
+ heap_close(catalogRelation, RowExclusiveLock);
}
/* --------------------------------
@@ -1001,7 +1000,7 @@ RelationRemoveIndexes(Relation relation)
HeapScanDesc scan;
ScanKeyData entry;
- indexRelation = heap_openr(IndexRelationName);
+ indexRelation = heap_openr(IndexRelationName, RowExclusiveLock);
ScanKeyEntryInitialize(&entry, 0x0, Anum_pg_index_indrelid,
F_OIDEQ,
@@ -1017,7 +1016,7 @@ RelationRemoveIndexes(Relation relation)
index_destroy(((Form_pg_index) GETSTRUCT(tuple))->indexrelid);
heap_endscan(scan);
- heap_close(indexRelation);
+ heap_close(indexRelation, RowExclusiveLock);
}
/* --------------------------------
@@ -1035,14 +1034,14 @@ DeleteRelationTuple(Relation rel)
* open pg_class
* ----------------
*/
- pg_class_desc = heap_openr(RelationRelationName);
+ pg_class_desc = heap_openr(RelationRelationName, RowExclusiveLock);
tup = SearchSysCacheTupleCopy(RELOID,
ObjectIdGetDatum(rel->rd_att->attrs[0]->attrelid),
0, 0, 0);
if (!HeapTupleIsValid(tup))
{
- heap_close(pg_class_desc);
+ heap_close(pg_class_desc, RowExclusiveLock);
elog(ERROR, "Relation '%s' does not exist",
&rel->rd_rel->relname);
}
@@ -1054,7 +1053,7 @@ DeleteRelationTuple(Relation rel)
heap_delete(pg_class_desc, &tup->t_self, NULL);
pfree(tup);
- heap_close(pg_class_desc);
+ heap_close(pg_class_desc, RowExclusiveLock);
}
/* --------------------------------
@@ -1073,13 +1072,7 @@ DeleteAttributeTuples(Relation rel)
* open pg_attribute
* ----------------
*/
- pg_attribute_desc = heap_openr(AttributeRelationName);
-
- /* -----------------
- * Get a write lock _before_ getting the read lock in the scan
- * ----------------
- */
- LockRelation(pg_attribute_desc, AccessExclusiveLock);
+ pg_attribute_desc = heap_openr(AttributeRelationName, RowExclusiveLock);
for (attnum = FirstLowInvalidHeapAttributeNumber + 1;
attnum <= rel->rd_att->natts;
@@ -1095,12 +1088,7 @@ DeleteAttributeTuples(Relation rel)
}
}
- /* ----------------
- * Release the write lock
- * ----------------
- */
- UnlockRelation(pg_attribute_desc, AccessExclusiveLock);
- heap_close(pg_attribute_desc);
+ heap_close(pg_attribute_desc, RowExclusiveLock);
}
/* --------------------------------
@@ -1129,7 +1117,7 @@ DeleteTypeTuple(Relation rel)
* open pg_type
* ----------------
*/
- pg_type_desc = heap_openr(TypeRelationName);
+ pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock);
/* ----------------
* create a scan key to locate the type tuple corresponding
@@ -1157,7 +1145,7 @@ DeleteTypeTuple(Relation rel)
if (!HeapTupleIsValid(tup))
{
heap_endscan(pg_type_scan);
- heap_close(pg_type_desc);
+ heap_close(pg_type_desc, RowExclusiveLock);
elog(ERROR, "DeleteTypeTuple: %s type nonexistent",
&rel->rd_rel->relname);
}
@@ -1171,7 +1159,7 @@ DeleteTypeTuple(Relation rel)
*/
typoid = tup->t_data->t_oid;
- pg_attribute_desc = heap_openr(AttributeRelationName);
+ pg_attribute_desc = heap_openr(AttributeRelationName, RowExclusiveLock);
ScanKeyEntryInitialize(&attkey,
0,
@@ -1197,16 +1185,16 @@ DeleteTypeTuple(Relation rel)
{
Oid relid = ((Form_pg_attribute) GETSTRUCT(atttup))->attrelid;
- heap_endscan(pg_type_scan);
- heap_close(pg_type_desc);
heap_endscan(pg_attribute_scan);
- heap_close(pg_attribute_desc);
+ heap_close(pg_attribute_desc, RowExclusiveLock);
+ heap_endscan(pg_type_scan);
+ heap_close(pg_type_desc, RowExclusiveLock);
elog(ERROR, "DeleteTypeTuple: att of type %s exists in relation %u",
&rel->rd_rel->relname, relid);
}
heap_endscan(pg_attribute_scan);
- heap_close(pg_attribute_desc);
+ heap_close(pg_attribute_desc, RowExclusiveLock);
/* ----------------
* Ok, it's safe so we delete the relation tuple
@@ -1217,7 +1205,7 @@ DeleteTypeTuple(Relation rel)
heap_delete(pg_type_desc, &tup->t_self, NULL);
heap_endscan(pg_type_scan);
- heap_close(pg_type_desc);
+ heap_close(pg_type_desc, RowExclusiveLock);
}
/* --------------------------------
@@ -1233,15 +1221,10 @@ heap_destroy_with_catalog(char *relname)
bool istemp = (get_temp_rel_by_name(relname) != NULL);
/* ----------------
- * first open the relation. if the relation doesn't exist,
- * heap_openr() returns NULL.
+ * Open and lock the relation.
* ----------------
*/
- rel = heap_openr(relname);
- if (rel == NULL)
- elog(ERROR, "Relation '%s' does not exist", relname);
-
- LockRelation(rel, AccessExclusiveLock);
+ rel = heap_openr(relname, AccessExclusiveLock);
rid = rel->rd_id;
/* ----------------
@@ -1249,8 +1232,8 @@ heap_destroy_with_catalog(char *relname)
* ----------------
*/
/* allow temp of pg_class? Guess so. */
- if (!istemp &&
- !allowSystemTableMods && IsSystemRelationName(RelationGetRelationName(rel)->data))
+ if (!istemp && !allowSystemTableMods &&
+ IsSystemRelationName(RelationGetRelationName(rel)->data))
elog(ERROR, "System relation '%s' cannot be destroyed",
&rel->rd_rel->relname);
@@ -1330,9 +1313,12 @@ heap_destroy_with_catalog(char *relname)
rel->rd_nonameunlinked = TRUE;
- UnlockRelation(rel, AccessExclusiveLock);
-
- heap_close(rel);
+ /*
+ * Close relcache entry, but *keep* AccessExclusiveLock on the
+ * relation until transaction commit. This ensures no one else
+ * will try to do something with the doomed relation.
+ */
+ heap_close(rel, NoLock);
/* ----------------
* flush the relation from the relcache
@@ -1354,7 +1340,7 @@ heap_destroy(Relation rel)
if (!(rel->rd_isnoname) || !(rel->rd_nonameunlinked))
smgrunlink(DEFAULT_SMGR, rel);
rel->rd_nonameunlinked = TRUE;
- heap_close(rel);
+ heap_close(rel, NoLock);
RemoveFromNoNameRelList(rel);
}
@@ -1542,13 +1528,13 @@ start:
values[Anum_pg_attrdef_adnum - 1] = attrdef->adnum;
values[Anum_pg_attrdef_adbin - 1] = PointerGetDatum(textin(attrdef->adbin));
values[Anum_pg_attrdef_adsrc - 1] = PointerGetDatum(textin(attrdef->adsrc));
- adrel = heap_openr(AttrDefaultRelationName);
+ adrel = heap_openr(AttrDefaultRelationName, RowExclusiveLock);
tuple = heap_formtuple(adrel->rd_att, values, nulls);
CatalogOpenIndices(Num_pg_attrdef_indices, Name_pg_attrdef_indices, idescs);
heap_insert(adrel, tuple);
CatalogIndexInsert(idescs, Num_pg_attrdef_indices, adrel, tuple);
CatalogCloseIndices(Num_pg_attrdef_indices, idescs);
- heap_close(adrel);
+ heap_close(adrel, RowExclusiveLock);
pfree(DatumGetPointer(values[Anum_pg_attrdef_adbin - 1]));
pfree(DatumGetPointer(values[Anum_pg_attrdef_adsrc - 1]));
@@ -1605,20 +1591,18 @@ StoreRelCheck(Relation rel, ConstrCheck *check)
values[Anum_pg_relcheck_rcname - 1] = PointerGetDatum(namein(check->ccname));
values[Anum_pg_relcheck_rcbin - 1] = PointerGetDatum(textin(check->ccbin));
values[Anum_pg_relcheck_rcsrc - 1] = PointerGetDatum(textin(check->ccsrc));
- rcrel = heap_openr(RelCheckRelationName);
+ rcrel = heap_openr(RelCheckRelationName, RowExclusiveLock);
tuple = heap_formtuple(rcrel->rd_att, values, nulls);
CatalogOpenIndices(Num_pg_relcheck_indices, Name_pg_relcheck_indices, idescs);
heap_insert(rcrel, tuple);
CatalogIndexInsert(idescs, Num_pg_relcheck_indices, rcrel, tuple);
CatalogCloseIndices(Num_pg_relcheck_indices, idescs);
- heap_close(rcrel);
+ heap_close(rcrel, RowExclusiveLock);
pfree(DatumGetPointer(values[Anum_pg_relcheck_rcname - 1]));
pfree(DatumGetPointer(values[Anum_pg_relcheck_rcbin - 1]));
pfree(DatumGetPointer(values[Anum_pg_relcheck_rcsrc - 1]));
pfree(tuple);
-
- return;
}
static void
@@ -1653,23 +1637,18 @@ RemoveAttrDefault(Relation rel)
ScanKeyData key;
HeapTuple tup;
- adrel = heap_openr(AttrDefaultRelationName);
+ adrel = heap_openr(AttrDefaultRelationName, RowExclusiveLock);
ScanKeyEntryInitialize(&key, 0, Anum_pg_attrdef_adrelid,
F_OIDEQ, rel->rd_id);
- LockRelation(adrel, AccessExclusiveLock);
-
adscan = heap_beginscan(adrel, 0, SnapshotNow, 1, &key);
while (HeapTupleIsValid(tup = heap_getnext(adscan, 0)))
heap_delete(adrel, &tup->t_self, NULL);
heap_endscan(adscan);
-
- UnlockRelation(adrel, AccessExclusiveLock);
- heap_close(adrel);
-
+ heap_close(adrel, RowExclusiveLock);
}
static void
@@ -1680,23 +1659,18 @@ RemoveRelCheck(Relation rel)
ScanKeyData key;
HeapTuple tup;
- rcrel = heap_openr(RelCheckRelationName);
+ rcrel = heap_openr(RelCheckRelationName, RowExclusiveLock);
ScanKeyEntryInitialize(&key, 0, Anum_pg_relcheck_rcrelid,
F_OIDEQ, rel->rd_id);
- LockRelation(rcrel, AccessExclusiveLock);
-
rcscan = heap_beginscan(rcrel, 0, SnapshotNow, 1, &key);
while (HeapTupleIsValid(tup = heap_getnext(rcscan, 0)))
heap_delete(rcrel, &tup->t_self, NULL);
heap_endscan(rcscan);
-
- UnlockRelation(rcrel, AccessExclusiveLock);
- heap_close(rcrel);
-
+ heap_close(rcrel, RowExclusiveLock);
}
static void
@@ -1712,6 +1686,4 @@ RemoveConstraints(Relation rel)
if (constr->num_check > 0)
RemoveRelCheck(rel);
-
- return;
}
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index c90c27fd5d..912996fb1f 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.89 1999/09/05 17:43:47 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.90 1999/09/18 19:06:33 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -378,7 +378,7 @@ AccessMethodObjectIdGetForm(Oid accessMethodObjectId)
* fetch the desired access method tuple
* ----------------
*/
- pg_am_desc = heap_openr(AccessMethodRelationName);
+ pg_am_desc = heap_openr(AccessMethodRelationName, AccessShareLock);
pg_am_scan = heap_beginscan(pg_am_desc, 0, SnapshotNow, 1, &key);
pg_am_tuple = heap_getnext(pg_am_scan, 0);
@@ -390,7 +390,7 @@ AccessMethodObjectIdGetForm(Oid accessMethodObjectId)
if (!HeapTupleIsValid(pg_am_tuple))
{
heap_endscan(pg_am_scan);
- heap_close(pg_am_desc);
+ heap_close(pg_am_desc, AccessShareLock);
return NULL;
}
@@ -402,7 +402,7 @@ AccessMethodObjectIdGetForm(Oid accessMethodObjectId)
memcpy(aform, GETSTRUCT(pg_am_tuple), sizeof *aform);
heap_endscan(pg_am_scan);
- heap_close(pg_am_desc);
+ heap_close(pg_am_desc, AccessShareLock);
return aform;
}
@@ -456,7 +456,7 @@ UpdateRelationRelation(Relation indexRelation, char *temp_relname)
Oid tupleOid;
Relation idescs[Num_pg_class_indices];
- pg_class = heap_openr(RelationRelationName);
+ pg_class = heap_openr(RelationRelationName, RowExclusiveLock);
/* XXX Natts_pg_class_fixed is a hack - see pg_class.h */
tuple = heap_addheader(Natts_pg_class_fixed,
@@ -491,7 +491,7 @@ UpdateRelationRelation(Relation indexRelation, char *temp_relname)
tupleOid = tuple->t_data->t_oid;
pfree(tuple);
- heap_close(pg_class);
+ heap_close(pg_class, RowExclusiveLock);
return tupleOid;
}
@@ -542,7 +542,7 @@ AppendAttributeTuples(Relation indexRelation, int numatts)
* XXX ADD INDEXING
* ----------------
*/
- pg_attribute = heap_openr(AttributeRelationName);
+ pg_attribute = heap_openr(AttributeRelationName, RowExclusiveLock);
/* ----------------
* initialize *null, *replace and *value
@@ -628,7 +628,7 @@ AppendAttributeTuples(Relation indexRelation, int numatts)
if (cur_tuple)
pfree(cur_tuple);
- heap_close(pg_attribute);
+ heap_close(pg_attribute, RowExclusiveLock);
if (hasind)
CatalogCloseIndices(Num_pg_attr_indices, idescs);
@@ -734,7 +734,7 @@ UpdateIndexRelation(Oid indexoid,
* open the system catalog index relation
* ----------------
*/
- pg_index = heap_openr(IndexRelationName);
+ pg_index = heap_openr(IndexRelationName, RowExclusiveLock);
/* ----------------
* form a tuple to insert into pg_index
@@ -755,7 +755,7 @@ UpdateIndexRelation(Oid indexoid,
* close the relation and free the tuple
* ----------------
*/
- heap_close(pg_index);
+ heap_close(pg_index, RowExclusiveLock);
pfree(predText);
pfree(indexForm);
pfree(tuple);
@@ -810,7 +810,7 @@ UpdateIndexPredicate(Oid indexoid, Node *oldPred, Node *predicate)
predText = (text *) fmgr(F_TEXTIN, "");
/* open the index system catalog relation */
- pg_index = heap_openr(IndexRelationName);
+ pg_index = heap_openr(IndexRelationName, RowExclusiveLock);
tuple = SearchSysCacheTuple(INDEXRELID,
ObjectIdGetDatum(indexoid),
@@ -832,7 +832,7 @@ UpdateIndexPredicate(Oid indexoid, Node *oldPred, Node *predicate)
heap_replace(pg_index, &newtup->t_self, newtup, NULL);
pfree(newtup);
- heap_close(pg_index);
+ heap_close(pg_index, RowExclusiveLock);
pfree(predText);
}
@@ -956,12 +956,10 @@ index_create(char *heapRelationName,
*/
heapoid = GetHeapRelationOid(heapRelationName, indexRelationName, istemp);
- heapRelation = heap_open(heapoid);
-
/*
- * Only SELECT ... FOR UPDATE are allowed
+ * Only SELECT ... FOR UPDATE are allowed while doing this
*/
- LockRelation(heapRelation, ShareLock);
+ heapRelation = heap_open(heapoid, ShareLock);
/* ----------------
* construct new tuple descriptor
@@ -1070,16 +1068,20 @@ index_create(char *heapRelationName,
* the index yet. We'll be creating more indices and classes later,
* so we delay filling them in until just before we're done with
* bootstrapping. Otherwise, we call the routine that constructs the
- * index. The heap and index relations are closed by index_build().
+ * index.
+ *
+ * In normal processing mode, the heap and index relations are closed
+ * by index_build() --- but we continue to hold the ShareLock on the
+ * heap that we acquired above, until end of transaction.
*/
if (IsBootstrapProcessingMode())
{
index_register(heapRelationName, indexRelationName, numatts, attNums,
parameterCount, parameter, funcInfo, predInfo);
+ /* XXX shouldn't we close the heap and index rels here? */
}
else
{
- heapRelation = heap_openr(heapRelationName);
index_build(heapRelation, indexRelation, numatts, attNums,
parameterCount, parameter, funcInfo, predInfo);
}
@@ -1103,9 +1105,13 @@ index_destroy(Oid indexId)
Assert(OidIsValid(indexId));
- /* Open now to obtain lock by referencing table? bjm */
userindexRelation = index_open(indexId);
+ /*
+ * Get exclusive lock to ensure no one else is scanning this index.
+ */
+ LockRelation(userindexRelation, AccessExclusiveLock);
+
/* ----------------
* We do not allow DROP INDEX within a transaction block, because
* if the transaction is later rolled back there would be no way to
@@ -1121,7 +1127,7 @@ index_destroy(Oid indexId)
* fix RELATION relation
* ----------------
*/
- relationRelation = heap_openr(RelationRelationName);
+ relationRelation = heap_openr(RelationRelationName, RowExclusiveLock);
tuple = SearchSysCacheTupleCopy(RELOID,
ObjectIdGetDatum(indexId),
@@ -1131,13 +1137,13 @@ index_destroy(Oid indexId)
heap_delete(relationRelation, &tuple->t_self, NULL);
pfree(tuple);
- heap_close(relationRelation);
+ heap_close(relationRelation, RowExclusiveLock);
/* ----------------
* fix ATTRIBUTE relation
* ----------------
*/
- attributeRelation = heap_openr(AttributeRelationName);
+ attributeRelation = heap_openr(AttributeRelationName, RowExclusiveLock);
attnum = 1; /* indexes start at 1 */
@@ -1150,7 +1156,7 @@ index_destroy(Oid indexId)
pfree(tuple);
attnum++;
}
- heap_close(attributeRelation);
+ heap_close(attributeRelation, RowExclusiveLock);
/* does something only if it is a temp index */
remove_temp_relation(indexId);
@@ -1159,16 +1165,16 @@ index_destroy(Oid indexId)
* fix INDEX relation
* ----------------
*/
+ indexRelation = heap_openr(IndexRelationName, RowExclusiveLock);
+
tuple = SearchSysCacheTupleCopy(INDEXRELID,
ObjectIdGetDatum(indexId),
0, 0, 0);
Assert(HeapTupleIsValid(tuple));
- indexRelation = heap_openr(IndexRelationName);
-
heap_delete(indexRelation, &tuple->t_self, NULL);
pfree(tuple);
- heap_close(indexRelation);
+ heap_close(indexRelation, RowExclusiveLock);
/*
* flush cache and physically remove the file
@@ -1179,7 +1185,8 @@ index_destroy(Oid indexId)
elog(ERROR, "index_destroy: unlink: %m");
index_close(userindexRelation);
- RelationForgetRelation(RelationGetRelid(userindexRelation));
+
+ RelationForgetRelation(indexId);
}
/* ----------------------------------------------------------------
@@ -1264,16 +1271,21 @@ UpdateStats(Oid relid, long reltuples, bool hasindex)
* ----------------
*/
+ /*
+ * Can't use heap_open here since we don't know if it's an index...
+ */
whichRel = RelationIdGetRelation(relid);
if (!RelationIsValid(whichRel))
elog(ERROR, "UpdateStats: cannot open relation id %u", relid);
+ LockRelation(whichRel, ShareLock);
+
/* ----------------
* Find the RELATION relation tuple for the given relation.
* ----------------
*/
- pg_class = heap_openr(RelationRelationName);
+ pg_class = heap_openr(RelationRelationName, RowExclusiveLock);
if (!RelationIsValid(pg_class))
elog(ERROR, "UpdateStats: could not open RELATION relation");
@@ -1300,7 +1312,7 @@ UpdateStats(Oid relid, long reltuples, bool hasindex)
{
if (IsBootstrapProcessingMode())
heap_endscan(pg_class_scan);
- heap_close(pg_class);
+ heap_close(pg_class, RowExclusiveLock);
elog(ERROR, "UpdateStats: cannot scan RELATION relation");
}
@@ -1391,8 +1403,9 @@ UpdateStats(Oid relid, long reltuples, bool hasindex)
else
heap_endscan(pg_class_scan);
- heap_close(pg_class);
- heap_close(whichRel);
+ heap_close(pg_class, RowExclusiveLock);
+ /* Cheating a little bit since we didn't open it with heap_open... */
+ heap_close(whichRel, ShareLock);
}
@@ -1600,20 +1613,31 @@ DefaultBuild(Relation heapRelation,
pfree(datum);
/*
- * Okay, now update the reltuples and relpages statistics for both the
- * heap relation and the index. These statistics are used by the
- * planner to choose a scan type. They are maintained generally by
- * the vacuum daemon, but we update them here to make the index useful
- * as soon as possible.
- */
- UpdateStats(RelationGetRelid(heapRelation), reltuples, true);
- UpdateStats(RelationGetRelid(indexRelation), indtuples, false);
- if (oldPred != NULL)
+ * Since we just counted the tuples in the heap, we update its stats
+ * in pg_class to guarantee that the planner takes advantage of the
+ * index we just created. But, only update statistics during
+ * normal index definitions, not for indices on system catalogs
+ * created during bootstrap processing. We must close the relations
+ * before updating statistics to guarantee that the relcache entries
+ * are flushed when we increment the command counter in UpdateStats().
+ * But we do not release any locks on the relations; those will be
+ * held until end of transaction.
+ */
+ if (IsNormalProcessingMode())
{
- if (indtuples == reltuples)
- predicate = NULL;
- UpdateIndexPredicate(RelationGetRelid(indexRelation),
- oldPred, predicate);
+ Oid hrelid = RelationGetRelid(heapRelation);
+ Oid irelid = RelationGetRelid(indexRelation);
+
+ heap_close(heapRelation, NoLock);
+ index_close(indexRelation);
+ UpdateStats(hrelid, reltuples, true);
+ UpdateStats(irelid, indtuples, false);
+ if (oldPred != NULL)
+ {
+ if (indtuples == reltuples)
+ predicate = NULL;
+ UpdateIndexPredicate(irelid, oldPred, predicate);
+ }
}
}
@@ -1715,7 +1739,7 @@ IndexIsUniqueNoCache(Oid indexId)
Form_pg_index index;
bool isunique;
- pg_index = heap_openr(IndexRelationName);
+ pg_index = heap_openr(IndexRelationName, AccessShareLock);
ScanKeyEntryInitialize(&skey[0], (bits16) 0x0,
Anum_pg_index_indexrelid,
@@ -1734,6 +1758,6 @@ IndexIsUniqueNoCache(Oid indexId)
isunique = index->indisunique;
heap_endscan(scandesc);
- heap_close(pg_index);
+ heap_close(pg_index, AccessShareLock);
return isunique;
}
diff --git a/src/backend/catalog/indexing.c b/src/backend/catalog/indexing.c
index 9007258f2e..75799e5557 100644
--- a/src/backend/catalog/indexing.c
+++ b/src/backend/catalog/indexing.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.44 1999/09/04 22:00:29 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.45 1999/09/18 19:06:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -193,9 +193,9 @@ CatalogHasIndex(char *catName, Oid catId)
return false;
}
- pg_class = heap_openr(RelationRelationName);
+ pg_class = heap_openr(RelationRelationName, AccessShareLock);
htup = ClassOidIndexScan(pg_class, catId);
- heap_close(pg_class);
+ heap_close(pg_class, AccessShareLock);
if (!HeapTupleIsValid(htup))
{
diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c
index c8f02287cb..0f2b98da90 100644
--- a/src/backend/catalog/pg_aggregate.c
+++ b/src/backend/catalog/pg_aggregate.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.24 1999/07/17 20:16:49 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_aggregate.c,v 1.25 1999/09/18 19:06:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -234,10 +234,7 @@ AggregateCreate(char *aggName,
else
nulls[Anum_pg_aggregate_agginitval2 - 1] = 'n';
- if (!RelationIsValid(aggdesc = heap_openr(AggregateRelationName)))
- elog(ERROR, "AggregateCreate: could not open '%s'",
- AggregateRelationName);
-
+ aggdesc = heap_openr(AggregateRelationName, RowExclusiveLock);
tupDesc = aggdesc->rd_att;
if (!HeapTupleIsValid(tup = heap_formtuple(tupDesc,
values,
@@ -245,8 +242,7 @@ AggregateCreate(char *aggName,
elog(ERROR, "AggregateCreate: heap_formtuple failed");
if (!OidIsValid(heap_insert(aggdesc, tup)))
elog(ERROR, "AggregateCreate: heap_insert failed");
- heap_close(aggdesc);
-
+ heap_close(aggdesc, RowExclusiveLock);
}
char *
@@ -264,6 +260,14 @@ AggNameGetInitVal(char *aggName, Oid basetype, int xfuncno, bool *isNull)
Assert(PointerIsValid(isNull));
Assert(xfuncno == 1 || xfuncno == 2);
+ /*
+ * since we will have to use fastgetattr (in case one or both init vals
+ * are NULL), we will need to open the relation. Do that first to
+ * ensure we don't get a stale tuple from the cache.
+ */
+
+ aggRel = heap_openr(AggregateRelationName, AccessShareLock);
+
tup = SearchSysCacheTuple(AGGNAME,
PointerGetDatum(aggName),
ObjectIdGetDatum(basetype),
@@ -277,21 +281,12 @@ AggNameGetInitVal(char *aggName, Oid basetype, int xfuncno, bool *isNull)
initValAttno = Anum_pg_aggregate_agginitval1;
}
else
- /* can only be 1 or 2 */
{
+ /* can only be 1 or 2 */
transtype = ((Form_pg_aggregate) GETSTRUCT(tup))->aggtranstype2;
initValAttno = Anum_pg_aggregate_agginitval2;
}
- aggRel = heap_openr(AggregateRelationName);
- if (!RelationIsValid(aggRel))
- elog(ERROR, "AggNameGetInitVal: could not open \"%-.*s\"",
- AggregateRelationName);
-
- /*
- * must use fastgetattr in case one or other of the init values is
- * NULL
- */
textInitVal = (text *) fastgetattr(tup, initValAttno,
RelationGetDescr(aggRel),
isNull);
@@ -299,11 +294,12 @@ AggNameGetInitVal(char *aggName, Oid basetype, int xfuncno, bool *isNull)
*isNull = true;
if (*isNull)
{
- heap_close(aggRel);
+ heap_close(aggRel, AccessShareLock);
return (char *) NULL;
}
strInitVal = textout(textInitVal);
- heap_close(aggRel);
+
+ heap_close(aggRel, AccessShareLock);
tup = SearchSysCacheTuple(TYPOID,
ObjectIdGetDatum(transtype),
diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c
index 8cab520f52..53b250fe3f 100644
--- a/src/backend/catalog/pg_operator.c
+++ b/src/backend/catalog/pg_operator.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.41 1999/07/17 20:16:49 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.42 1999/09/18 19:06:33 tgl Exp $
*
* NOTES
* these routines moved here from commands/define.c and somewhat cleaned up.
@@ -199,7 +199,7 @@ OperatorGet(char *operatorName,
* open the pg_operator relation
* ----------------
*/
- pg_operator_desc = heap_openr(OperatorRelationName);
+ pg_operator_desc = heap_openr(OperatorRelationName, AccessShareLock);
/* ----------------
* get the oid for the operator with the appropriate name
@@ -216,7 +216,7 @@ OperatorGet(char *operatorName,
* close the relation and return the operator oid.
* ----------------
*/
- heap_close(pg_operator_desc);
+ heap_close(pg_operator_desc, AccessShareLock);
return operatorObjectId;
}
@@ -341,7 +341,7 @@ OperatorShellMake(char *operatorName,
* open pg_operator
* ----------------
*/
- pg_operator_desc = heap_openr(OperatorRelationName);
+ pg_operator_desc = heap_openr(OperatorRelationName, RowExclusiveLock);
/* ----------------
* add a "shell" operator tuple to the operator relation
@@ -356,7 +356,7 @@ OperatorShellMake(char *operatorName,
* close the operator relation and return the oid.
* ----------------
*/
- heap_close(pg_operator_desc);
+ heap_close(pg_operator_desc, RowExclusiveLock);
return operatorObjectId;
}
@@ -754,10 +754,11 @@ OperatorDef(char *operatorName,
/* last three fields were filled in above */
+ pg_operator_desc = heap_openr(OperatorRelationName, RowExclusiveLock);
+
/*
* If we are adding to an operator shell, get its t_self
*/
- pg_operator_desc = heap_openr(OperatorRelationName);
if (operatorObjectId)
{
@@ -798,7 +799,7 @@ OperatorDef(char *operatorName,
operatorObjectId = tup->t_data->t_oid;
}
- heap_close(pg_operator_desc);
+ heap_close(pg_operator_desc, RowExclusiveLock);
/*
* If a commutator and/or negator link is provided, update the other
@@ -853,7 +854,7 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId)
nulls[i] = ' ';
}
- pg_operator_desc = heap_openr(OperatorRelationName);
+ pg_operator_desc = heap_openr(OperatorRelationName, RowExclusiveLock);
/* check and update the commutator, if necessary */
opKey[0].sk_argument = ObjectIdGetDatum(commId);
@@ -908,7 +909,7 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId)
}
heap_endscan(pg_operator_scan);
- heap_close(pg_operator_desc);
+ heap_close(pg_operator_desc, RowExclusiveLock);
return;
}
@@ -964,7 +965,7 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId)
heap_endscan(pg_operator_scan);
- heap_close(pg_operator_desc);
+ heap_close(pg_operator_desc, RowExclusiveLock);
}
diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
index f0a10cf8f8..b71f36e661 100644
--- a/src/backend/catalog/pg_proc.c
+++ b/src/backend/catalog/pg_proc.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.33 1999/07/17 20:16:49 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.34 1999/09/18 19:06:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -277,7 +277,7 @@ ProcedureCreate(char *procedureName,
values[i++] = (Datum) fmgr(F_TEXTIN, prosrc); /* prosrc */
values[i++] = (Datum) fmgr(F_TEXTIN, probin); /* probin */
- rel = heap_openr(ProcedureRelationName);
+ rel = heap_openr(ProcedureRelationName, RowExclusiveLock);
tupDesc = rel->rd_att;
tup = heap_formtuple(tupDesc,
@@ -294,6 +294,6 @@ ProcedureCreate(char *procedureName,
CatalogIndexInsert(idescs, Num_pg_proc_indices, rel, tup);
CatalogCloseIndices(Num_pg_proc_indices, idescs);
}
- heap_close(rel);
+ heap_close(rel, RowExclusiveLock);
return tup->t_data->t_oid;
}
diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c
index a219767858..91c7cd995b 100644
--- a/src/backend/catalog/pg_type.c
+++ b/src/backend/catalog/pg_type.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.40 1999/07/17 20:16:50 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.41 1999/09/18 19:06:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -119,7 +119,7 @@ TypeGet(char *typeName, /* name of type to be fetched */
* open the pg_type relation
* ----------------
*/
- pg_type_desc = heap_openr(TypeRelationName);
+ pg_type_desc = heap_openr(TypeRelationName, AccessShareLock);
/* ----------------
* scan the type relation for the information we want
@@ -133,7 +133,7 @@ TypeGet(char *typeName, /* name of type to be fetched */
* close the type relation and return the type oid.
* ----------------
*/
- heap_close(pg_type_desc);
+ heap_close(pg_type_desc, AccessShareLock);
return typeoid;
}
@@ -248,7 +248,7 @@ TypeShellMake(char *typeName)
* open pg_type
* ----------------
*/
- pg_type_desc = heap_openr(TypeRelationName);
+ pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock);
/* ----------------
* insert the shell tuple
@@ -260,7 +260,7 @@ TypeShellMake(char *typeName)
* close pg_type and return the tuple's oid.
* ----------------
*/
- heap_close(pg_type_desc);
+ heap_close(pg_type_desc, RowExclusiveLock);
return typoid;
}
@@ -457,14 +457,7 @@ TypeCreate(char *typeName,
* open pg_type and begin a scan for the type name.
* ----------------
*/
- pg_type_desc = heap_openr(TypeRelationName);
-
- /* -----------------
- * Set a write lock initially so as not upgrade a read to a write
- * when the heap_insert() or heap_replace() is called.
- * -----------------
- */
- LockRelation(pg_type_desc, AccessExclusiveLock);
+ pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock);
typeKey[0].sk_argument = PointerGetDatum(typeName);
pg_type_scan = heap_beginscan(pg_type_desc,
@@ -521,8 +514,8 @@ TypeCreate(char *typeName,
CatalogIndexInsert(idescs, Num_pg_type_indices, pg_type_desc, tup);
CatalogCloseIndices(Num_pg_type_indices, idescs);
}
- UnlockRelation(pg_type_desc, AccessExclusiveLock);
- heap_close(pg_type_desc);
+
+ heap_close(pg_type_desc, RowExclusiveLock);
return typeObjectId;
}
@@ -541,7 +534,7 @@ TypeRename(char *oldTypeName, char *newTypeName)
HeapTuple oldtup,
newtup;
- pg_type_desc = heap_openr(TypeRelationName);
+ pg_type_desc = heap_openr(TypeRelationName, RowExclusiveLock);
oldtup = SearchSysCacheTupleCopy(TYPNAME,
PointerGetDatum(oldTypeName),
@@ -549,7 +542,7 @@ TypeRename(char *oldTypeName, char *newTypeName)
if (!HeapTupleIsValid(oldtup))
{
- heap_close(pg_type_desc);
+ heap_close(pg_type_desc, RowExclusiveLock);
elog(ERROR, "TypeRename: type %s not defined", oldTypeName);
}
@@ -559,7 +552,7 @@ TypeRename(char *oldTypeName, char *newTypeName)
if (HeapTupleIsValid(newtup))
{
pfree(oldtup);
- heap_close(pg_type_desc);
+ heap_close(pg_type_desc, RowExclusiveLock);
elog(ERROR, "TypeRename: type %s already defined", newTypeName);
}
@@ -575,7 +568,7 @@ TypeRename(char *oldTypeName, char *newTypeName)
CatalogCloseIndices(Num_pg_type_indices, idescs);
pfree(oldtup);
- heap_close(pg_type_desc);
+ heap_close(pg_type_desc, RowExclusiveLock);
}
/*