aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/heap
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/heap')
-rw-r--r--src/backend/access/heap/heapam.c66
-rw-r--r--src/backend/access/heap/tuptoaster.c31
2 files changed, 53 insertions, 44 deletions
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 91460410bf9..f29407e8e5d 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.217 2006/07/14 14:52:17 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.218 2006/07/31 20:08:59 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -51,6 +51,7 @@
#include "pgstat.h"
#include "storage/procarray.h"
#include "utils/inval.h"
+#include "utils/lsyscache.h"
#include "utils/relcache.h"
@@ -687,15 +688,16 @@ relation_open(Oid relationId, LOCKMODE lockmode)
Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES);
+ /* Get the lock before trying to open the relcache entry */
+ if (lockmode != NoLock)
+ LockRelationOid(relationId, lockmode);
+
/* The relcache does all the real work... */
r = RelationIdGetRelation(relationId);
if (!RelationIsValid(r))
elog(ERROR, "could not open relation with OID %u", relationId);
- if (lockmode != NoLock)
- LockRelation(r, lockmode);
-
return r;
}
@@ -713,26 +715,38 @@ conditional_relation_open(Oid relationId, LOCKMODE lockmode, bool nowait)
Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES);
- /* The relcache does all the real work... */
- r = RelationIdGetRelation(relationId);
-
- if (!RelationIsValid(r))
- elog(ERROR, "could not open relation with OID %u", relationId);
-
+ /* Get the lock before trying to open the relcache entry */
if (lockmode != NoLock)
{
if (nowait)
{
- if (!ConditionalLockRelation(r, lockmode))
- ereport(ERROR,
- (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
- errmsg("could not obtain lock on relation \"%s\"",
- RelationGetRelationName(r))));
+ if (!ConditionalLockRelationOid(relationId, lockmode))
+ {
+ /* try to throw error by name; relation could be deleted... */
+ char *relname = get_rel_name(relationId);
+
+ if (relname)
+ ereport(ERROR,
+ (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
+ errmsg("could not obtain lock on relation \"%s\"",
+ relname)));
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
+ errmsg("could not obtain lock on relation with OID %u",
+ relationId)));
+ }
}
else
- LockRelation(r, lockmode);
+ LockRelationOid(relationId, lockmode);
}
+ /* The relcache does all the real work... */
+ r = RelationIdGetRelation(relationId);
+
+ if (!RelationIsValid(r))
+ elog(ERROR, "could not open relation with OID %u", relationId);
+
return r;
}
@@ -749,12 +763,12 @@ relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
/*
* Check for shared-cache-inval messages before trying to open the
- * relation. This is needed to cover the case where the name identifies a
- * rel that has been dropped and recreated since the start of our
+ * relation. This is needed to cover the case where the name identifies
+ * a rel that has been dropped and recreated since the start of our
* transaction: if we don't flush the old syscache entry then we'll latch
- * onto that entry and suffer an error when we do LockRelation. Note that
- * relation_open does not need to do this, since a relation's OID never
- * changes.
+ * onto that entry and suffer an error when we do RelationIdGetRelation.
+ * Note that relation_open does not need to do this, since a relation's
+ * OID never changes.
*
* We skip this if asked for NoLock, on the assumption that the caller has
* already ensured some appropriate lock is held.
@@ -772,7 +786,7 @@ relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
/* ----------------
* relation_close - close any relation
*
- * If lockmode is not "NoLock", we first release the specified lock.
+ * If lockmode is not "NoLock", we then release the specified lock.
*
* Note that it is often sensible to hold a lock beyond relation_close;
* in that case, the lock is released automatically at xact end.
@@ -781,13 +795,15 @@ relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
void
relation_close(Relation relation, LOCKMODE lockmode)
{
- Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES);
+ LockRelId relid = relation->rd_lockInfo.lockRelId;
- if (lockmode != NoLock)
- UnlockRelation(relation, lockmode);
+ Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES);
/* The relcache does the real work... */
RelationClose(relation);
+
+ if (lockmode != NoLock)
+ UnlockRelationId(&relid, lockmode);
}
diff --git a/src/backend/access/heap/tuptoaster.c b/src/backend/access/heap/tuptoaster.c
index 11adf165c45..43ca366f0a6 100644
--- a/src/backend/access/heap/tuptoaster.c
+++ b/src/backend/access/heap/tuptoaster.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.62 2006/07/14 14:52:17 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/access/heap/tuptoaster.c,v 1.63 2006/07/31 20:08:59 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -1004,7 +1004,7 @@ toast_save_datum(Relation rel, Datum value)
*/
toastrel = heap_open(rel->rd_rel->reltoastrelid, RowExclusiveLock);
toasttupDesc = toastrel->rd_att;
- toastidx = index_open(toastrel->rd_rel->reltoastidxid);
+ toastidx = index_open(toastrel->rd_rel->reltoastidxid, RowExclusiveLock);
/*
* Create the varattrib reference
@@ -1044,12 +1044,6 @@ toast_save_datum(Relation rel, Datum value)
data_todo = VARATT_SIZE(value) - VARHDRSZ;
/*
- * We must explicitly lock the toast index because we aren't using an
- * index scan here.
- */
- LockRelation(toastidx, RowExclusiveLock);
-
- /*
* Split up the item into chunks
*/
while (data_todo > 0)
@@ -1098,8 +1092,7 @@ toast_save_datum(Relation rel, Datum value)
/*
* Done - close toast relation and return the reference
*/
- UnlockRelation(toastidx, RowExclusiveLock);
- index_close(toastidx);
+ index_close(toastidx, RowExclusiveLock);
heap_close(toastrel, RowExclusiveLock);
return PointerGetDatum(result);
@@ -1130,7 +1123,7 @@ toast_delete_datum(Relation rel, Datum value)
*/
toastrel = heap_open(attr->va_content.va_external.va_toastrelid,
RowExclusiveLock);
- toastidx = index_open(toastrel->rd_rel->reltoastidxid);
+ toastidx = index_open(toastrel->rd_rel->reltoastidxid, RowExclusiveLock);
/*
* Setup a scan key to fetch from the index by va_valueid (we don't
@@ -1144,7 +1137,7 @@ toast_delete_datum(Relation rel, Datum value)
/*
* Find the chunks by index
*/
- toastscan = index_beginscan(toastrel, toastidx, true,
+ toastscan = index_beginscan(toastrel, toastidx,
SnapshotToast, 1, &toastkey);
while ((toasttup = index_getnext(toastscan, ForwardScanDirection)) != NULL)
{
@@ -1158,7 +1151,7 @@ toast_delete_datum(Relation rel, Datum value)
* End scan and close relations
*/
index_endscan(toastscan);
- index_close(toastidx);
+ index_close(toastidx, RowExclusiveLock);
heap_close(toastrel, RowExclusiveLock);
}
@@ -1202,7 +1195,7 @@ toast_fetch_datum(varattrib *attr)
toastrel = heap_open(attr->va_content.va_external.va_toastrelid,
AccessShareLock);
toasttupDesc = toastrel->rd_att;
- toastidx = index_open(toastrel->rd_rel->reltoastidxid);
+ toastidx = index_open(toastrel->rd_rel->reltoastidxid, AccessShareLock);
/*
* Setup a scan key to fetch from the index by va_valueid
@@ -1221,7 +1214,7 @@ toast_fetch_datum(varattrib *attr)
*/
nextidx = 0;
- toastscan = index_beginscan(toastrel, toastidx, true,
+ toastscan = index_beginscan(toastrel, toastidx,
SnapshotToast, 1, &toastkey);
while ((ttup = index_getnext(toastscan, ForwardScanDirection)) != NULL)
{
@@ -1282,7 +1275,7 @@ toast_fetch_datum(varattrib *attr)
* End scan and close relations
*/
index_endscan(toastscan);
- index_close(toastidx);
+ index_close(toastidx, AccessShareLock);
heap_close(toastrel, AccessShareLock);
return result;
@@ -1355,7 +1348,7 @@ toast_fetch_datum_slice(varattrib *attr, int32 sliceoffset, int32 length)
toastrel = heap_open(attr->va_content.va_external.va_toastrelid,
AccessShareLock);
toasttupDesc = toastrel->rd_att;
- toastidx = index_open(toastrel->rd_rel->reltoastidxid);
+ toastidx = index_open(toastrel->rd_rel->reltoastidxid, AccessShareLock);
/*
* Setup a scan key to fetch from the index. This is either two keys or
@@ -1396,7 +1389,7 @@ toast_fetch_datum_slice(varattrib *attr, int32 sliceoffset, int32 length)
* The index is on (valueid, chunkidx) so they will come in order
*/
nextidx = startchunk;
- toastscan = index_beginscan(toastrel, toastidx, true,
+ toastscan = index_beginscan(toastrel, toastidx,
SnapshotToast, nscankeys, toastkey);
while ((ttup = index_getnext(toastscan, ForwardScanDirection)) != NULL)
{
@@ -1461,7 +1454,7 @@ toast_fetch_datum_slice(varattrib *attr, int32 sliceoffset, int32 length)
* End scan and close relations
*/
index_endscan(toastscan);
- index_close(toastidx);
+ index_close(toastidx, AccessShareLock);
heap_close(toastrel, AccessShareLock);
return result;