summaryrefslogtreecommitdiff
path: root/src/backend/catalog
diff options
context:
space:
mode:
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);
}
/*