diff options
Diffstat (limited to 'src/backend/catalog/heap.c')
| -rw-r--r-- | src/backend/catalog/heap.c | 132 |
1 files changed, 52 insertions, 80 deletions
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; } |
