diff options
Diffstat (limited to 'src/backend/catalog')
| -rw-r--r-- | src/backend/catalog/aclchk.c | 69 | ||||
| -rw-r--r-- | src/backend/catalog/heap.c | 132 | ||||
| -rw-r--r-- | src/backend/catalog/index.c | 116 | ||||
| -rw-r--r-- | src/backend/catalog/indexing.c | 6 | ||||
| -rw-r--r-- | src/backend/catalog/pg_aggregate.c | 34 | ||||
| -rw-r--r-- | src/backend/catalog/pg_operator.c | 21 | ||||
| -rw-r--r-- | src/backend/catalog/pg_proc.c | 6 | ||||
| -rw-r--r-- | src/backend/catalog/pg_type.c | 31 |
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); } /* |
