Commit 3f7fbf85 authored by Vadim B. Mikheev's avatar Vadim B. Mikheev

Initial MVCC code.

New code for locking buffer' context.
parent c5a27161
...@@ -104,8 +104,7 @@ gistbuild(Relation heap, ...@@ -104,8 +104,7 @@ gistbuild(Relation heap,
Buffer buffer = InvalidBuffer; Buffer buffer = InvalidBuffer;
bool *compvec; bool *compvec;
/* GiSTs only know how to do stupid locking now */ /* no locking is needed */
RelationSetLockForWrite(index);
setheapoverride(true); /* so we can see the new pg_index tuple */ setheapoverride(true); /* so we can see the new pg_index tuple */
initGISTstate(&giststate, index); initGISTstate(&giststate, index);
...@@ -269,7 +268,6 @@ gistbuild(Relation heap, ...@@ -269,7 +268,6 @@ gistbuild(Relation heap,
/* okay, all heap tuples are indexed */ /* okay, all heap tuples are indexed */
heap_endscan(scan); heap_endscan(scan);
RelationUnsetLockForWrite(index);
if (pred != NULL || oldPred != NULL) if (pred != NULL || oldPred != NULL)
{ {
...@@ -343,7 +341,12 @@ gistinsert(Relation r, Datum *datum, char *nulls, ItemPointer ht_ctid, Relation ...@@ -343,7 +341,12 @@ gistinsert(Relation r, Datum *datum, char *nulls, ItemPointer ht_ctid, Relation
itup = index_formtuple(RelationGetDescr(r), datum, nulls); itup = index_formtuple(RelationGetDescr(r), datum, nulls);
itup->t_tid = *ht_ctid; itup->t_tid = *ht_ctid;
/*
* Notes in ExecUtils:ExecOpenIndices()
*
RelationSetLockForWrite(r); RelationSetLockForWrite(r);
*/
res = gistdoinsert(r, itup, &giststate); res = gistdoinsert(r, itup, &giststate);
for (i = 0; i < r->rd_att->natts; i++) for (i = 0; i < r->rd_att->natts; i++)
if (compvec[i] == TRUE) if (compvec[i] == TRUE)
...@@ -351,7 +354,6 @@ gistinsert(Relation r, Datum *datum, char *nulls, ItemPointer ht_ctid, Relation ...@@ -351,7 +354,6 @@ gistinsert(Relation r, Datum *datum, char *nulls, ItemPointer ht_ctid, Relation
pfree(itup); pfree(itup);
pfree(compvec); pfree(compvec);
/* XXX two-phase locking -- don't unlock the relation until EOT */
return res; return res;
} }
...@@ -1103,8 +1105,12 @@ gistdelete(Relation r, ItemPointer tid) ...@@ -1103,8 +1105,12 @@ gistdelete(Relation r, ItemPointer tid)
Buffer buf; Buffer buf;
Page page; Page page;
/* must write-lock on delete */ /*
* Notes in ExecUtils:ExecOpenIndices()
* Also note that only vacuum deletes index tuples now...
*
RelationSetLockForWrite(r); RelationSetLockForWrite(r);
*/
blkno = ItemPointerGetBlockNumber(tid); blkno = ItemPointerGetBlockNumber(tid);
offnum = ItemPointerGetOffsetNumber(tid); offnum = ItemPointerGetOffsetNumber(tid);
...@@ -1120,7 +1126,6 @@ gistdelete(Relation r, ItemPointer tid) ...@@ -1120,7 +1126,6 @@ gistdelete(Relation r, ItemPointer tid)
WriteBuffer(buf); WriteBuffer(buf);
/* XXX -- two-phase locking, don't release the write lock */
} }
void void
......
...@@ -65,7 +65,12 @@ gistbeginscan(Relation r, ...@@ -65,7 +65,12 @@ gistbeginscan(Relation r,
{ {
IndexScanDesc s; IndexScanDesc s;
/*
* Let index_beginscan does its work...
*
RelationSetLockForRead(r); RelationSetLockForRead(r);
*/
s = RelationGetIndexScan(r, fromEnd, nkeys, key); s = RelationGetIndexScan(r, fromEnd, nkeys, key);
gistregscan(s); gistregscan(s);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashpage.c,v 1.17 1998/09/01 03:20:58 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/hash/hashpage.c,v 1.18 1998/12/15 12:45:10 vadim Exp $
* *
* NOTES * NOTES
* Postgres hash pages look like ordinary relation pages. The opaque * Postgres hash pages look like ordinary relation pages. The opaque
...@@ -81,7 +81,7 @@ _hash_metapinit(Relation rel) ...@@ -81,7 +81,7 @@ _hash_metapinit(Relation rel)
/* can't be sharing this with anyone, now... */ /* can't be sharing this with anyone, now... */
if (USELOCKING) if (USELOCKING)
RelationSetLockForWrite(rel); LockRelation(rel, AccessExclusiveLock);
if ((nblocks = RelationGetNumberOfBlocks(rel)) != 0) if ((nblocks = RelationGetNumberOfBlocks(rel)) != 0)
{ {
...@@ -169,7 +169,7 @@ _hash_metapinit(Relation rel) ...@@ -169,7 +169,7 @@ _hash_metapinit(Relation rel)
_hash_relbuf(rel, metabuf, HASH_WRITE); _hash_relbuf(rel, metabuf, HASH_WRITE);
if (USELOCKING) if (USELOCKING)
RelationUnsetLockForWrite(rel); UnlockRelation(rel, AccessExclusiveLock);
} }
/* /*
...@@ -316,19 +316,16 @@ _hash_setpagelock(Relation rel, ...@@ -316,19 +316,16 @@ _hash_setpagelock(Relation rel,
BlockNumber blkno, BlockNumber blkno,
int access) int access)
{ {
ItemPointerData iptr;
if (USELOCKING) if (USELOCKING)
{ {
ItemPointerSet(&iptr, blkno, 1);
switch (access) switch (access)
{ {
case HASH_WRITE: case HASH_WRITE:
RelationSetSingleWLockPage(rel, &iptr); LockPage(rel, blkno, ExclusiveLock);
break; break;
case HASH_READ: case HASH_READ:
RelationSetSingleRLockPage(rel, &iptr); LockPage(rel, blkno, ShareLock);
break; break;
default: default:
elog(ERROR, "_hash_setpagelock: invalid access (%d) on blk %x: %s", elog(ERROR, "_hash_setpagelock: invalid access (%d) on blk %x: %s",
...@@ -343,19 +340,16 @@ _hash_unsetpagelock(Relation rel, ...@@ -343,19 +340,16 @@ _hash_unsetpagelock(Relation rel,
BlockNumber blkno, BlockNumber blkno,
int access) int access)
{ {
ItemPointerData iptr;
if (USELOCKING) if (USELOCKING)
{ {
ItemPointerSet(&iptr, blkno, 1);
switch (access) switch (access)
{ {
case HASH_WRITE: case HASH_WRITE:
RelationUnsetSingleWLockPage(rel, &iptr); UnlockPage(rel, blkno, ExclusiveLock);
break; break;
case HASH_READ: case HASH_READ:
RelationUnsetSingleRLockPage(rel, &iptr); UnlockPage(rel, blkno, ShareLock);
break; break;
default: default:
elog(ERROR, "_hash_unsetpagelock: invalid access (%d) on blk %x: %s", elog(ERROR, "_hash_unsetpagelock: invalid access (%d) on blk %x: %s",
......
This diff is collapsed.
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Id: hio.c,v 1.14 1998/11/27 19:51:36 vadim Exp $ * $Id: hio.c,v 1.15 1998/12/15 12:45:14 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <postgres.h> #include <postgres.h>
#include <storage/bufpage.h> #include <storage/bufpage.h>
#include <access/hio.h>
#include <access/heapam.h> #include <access/heapam.h>
#include <storage/bufmgr.h> #include <storage/bufmgr.h>
#include <utils/memutils.h> #include <utils/memutils.h>
...@@ -29,19 +30,20 @@ ...@@ -29,19 +30,20 @@
* Probably needs to have an amdelunique to allow for * Probably needs to have an amdelunique to allow for
* internal index records to be deleted and reordered as needed. * internal index records to be deleted and reordered as needed.
* For the heap AM, this should never be needed. * For the heap AM, this should never be needed.
*
* Note - we assume that caller hold BUFFER_LOCK_EXCLUSIVE on the buffer.
*
*/ */
void void
RelationPutHeapTuple(Relation relation, RelationPutHeapTuple(Relation relation,
BlockNumber blockIndex, Buffer buffer,
HeapTuple tuple) HeapTuple tuple)
{ {
Buffer buffer; Page pageHeader;
Page pageHeader; OffsetNumber offnum;
BlockNumber numberOfBlocks; unsigned int len;
OffsetNumber offnum; ItemId itemId;
unsigned int len; Item item;
ItemId itemId;
Item item;
/* ---------------- /* ----------------
* increment access statistics * increment access statistics
...@@ -50,21 +52,6 @@ RelationPutHeapTuple(Relation relation, ...@@ -50,21 +52,6 @@ RelationPutHeapTuple(Relation relation,
IncrHeapAccessStat(local_RelationPutHeapTuple); IncrHeapAccessStat(local_RelationPutHeapTuple);
IncrHeapAccessStat(global_RelationPutHeapTuple); IncrHeapAccessStat(global_RelationPutHeapTuple);
Assert(RelationIsValid(relation));
Assert(HeapTupleIsValid(tuple));
numberOfBlocks = RelationGetNumberOfBlocks(relation);
Assert(blockIndex < numberOfBlocks);
buffer = ReadBuffer(relation, blockIndex);
#ifndef NO_BUFFERISVALID
if (!BufferIsValid(buffer))
{
elog(ERROR, "RelationPutHeapTuple: no buffer for %ld in %s",
blockIndex, &relation->rd_rel->relname);
}
#endif
pageHeader = (Page) BufferGetPage(buffer); pageHeader = (Page) BufferGetPage(buffer);
len = (unsigned) DOUBLEALIGN(tuple->t_len); /* be conservative */ len = (unsigned) DOUBLEALIGN(tuple->t_len); /* be conservative */
Assert((int) len <= PageGetFreeSpace(pageHeader)); Assert((int) len <= PageGetFreeSpace(pageHeader));
...@@ -75,11 +62,17 @@ RelationPutHeapTuple(Relation relation, ...@@ -75,11 +62,17 @@ RelationPutHeapTuple(Relation relation,
itemId = PageGetItemId((Page) pageHeader, offnum); itemId = PageGetItemId((Page) pageHeader, offnum);
item = PageGetItem((Page) pageHeader, itemId); item = PageGetItem((Page) pageHeader, itemId);
ItemPointerSet(&((HeapTupleHeader) item)->t_ctid, blockIndex, offnum); ItemPointerSet(&((HeapTupleHeader) item)->t_ctid,
BufferGetBlockNumber(buffer), offnum);
/*
* Let the caller do this!
*
WriteBuffer(buffer); WriteBuffer(buffer);
*/
/* return an accurate tuple */ /* return an accurate tuple */
ItemPointerSet(&tuple->t_self, blockIndex, offnum); ItemPointerSet(&tuple->t_self, BufferGetBlockNumber(buffer), offnum);
} }
/* /*
...@@ -99,6 +92,7 @@ RelationPutHeapTuple(Relation relation, ...@@ -99,6 +92,7 @@ RelationPutHeapTuple(Relation relation,
* RelationGetNumberOfBlocks to be useful. * RelationGetNumberOfBlocks to be useful.
* *
* NOTE: This code presumes that we have a write lock on the relation. * NOTE: This code presumes that we have a write lock on the relation.
* Not now - we use extend locking...
* *
* Also note that this routine probably shouldn't have to exist, and does * Also note that this routine probably shouldn't have to exist, and does
* screw up the call graph rather badly, but we are wasting so much time and * screw up the call graph rather badly, but we are wasting so much time and
...@@ -116,8 +110,8 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple) ...@@ -116,8 +110,8 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
ItemId itemId; ItemId itemId;
Item item; Item item;
Assert(RelationIsValid(relation)); if (!relation->rd_islocal)
Assert(HeapTupleIsValid(tuple)); LockRelation(relation, ExtendLock);
/* /*
* XXX This does an lseek - VERY expensive - but at the moment it is * XXX This does an lseek - VERY expensive - but at the moment it is
...@@ -132,16 +126,18 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple) ...@@ -132,16 +126,18 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
{ {
buffer = ReadBuffer(relation, lastblock); buffer = ReadBuffer(relation, lastblock);
pageHeader = (Page) BufferGetPage(buffer); pageHeader = (Page) BufferGetPage(buffer);
if (PageIsNew((PageHeader) pageHeader)) /*
{ * There was IF instead of ASSERT here ?!
buffer = ReleaseAndReadBuffer(buffer, relation, P_NEW); */
pageHeader = (Page) BufferGetPage(buffer); Assert(PageIsNew((PageHeader) pageHeader));
PageInit(pageHeader, BufferGetPageSize(buffer), 0); buffer = ReleaseAndReadBuffer(buffer, relation, P_NEW);
} pageHeader = (Page) BufferGetPage(buffer);
PageInit(pageHeader, BufferGetPageSize(buffer), 0);
} }
else else
buffer = ReadBuffer(relation, lastblock - 1); buffer = ReadBuffer(relation, lastblock - 1);
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
pageHeader = (Page) BufferGetPage(buffer); pageHeader = (Page) BufferGetPage(buffer);
len = (unsigned) DOUBLEALIGN(tuple->t_len); /* be conservative */ len = (unsigned) DOUBLEALIGN(tuple->t_len); /* be conservative */
...@@ -152,7 +148,9 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple) ...@@ -152,7 +148,9 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
if (len > PageGetFreeSpace(pageHeader)) if (len > PageGetFreeSpace(pageHeader))
{ {
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
buffer = ReleaseAndReadBuffer(buffer, relation, P_NEW); buffer = ReleaseAndReadBuffer(buffer, relation, P_NEW);
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
pageHeader = (Page) BufferGetPage(buffer); pageHeader = (Page) BufferGetPage(buffer);
PageInit(pageHeader, BufferGetPageSize(buffer), 0); PageInit(pageHeader, BufferGetPageSize(buffer), 0);
...@@ -160,6 +158,9 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple) ...@@ -160,6 +158,9 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
elog(ERROR, "Tuple is too big: size %d", len); elog(ERROR, "Tuple is too big: size %d", len);
} }
if (!relation->rd_islocal)
UnlockRelation(relation, ExtendLock);
offnum = PageAddItem((Page) pageHeader, (Item) tuple->t_data, offnum = PageAddItem((Page) pageHeader, (Item) tuple->t_data,
tuple->t_len, InvalidOffsetNumber, LP_USED); tuple->t_len, InvalidOffsetNumber, LP_USED);
...@@ -173,5 +174,7 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple) ...@@ -173,5 +174,7 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
/* return an accurate tuple */ /* return an accurate tuple */
ItemPointerSet(&tuple->t_self, lastblock, offnum); ItemPointerSet(&tuple->t_self, lastblock, offnum);
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
WriteBuffer(buffer); WriteBuffer(buffer);
} }
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/heap/Attic/stats.c,v 1.13 1997/09/08 02:20:31 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/heap/Attic/stats.c,v 1.14 1998/12/15 12:45:15 vadim Exp $
* *
* NOTES * NOTES
* initam should be moved someplace else. * initam should be moved someplace else.
...@@ -73,6 +73,7 @@ InitHeapAccessStatistics() ...@@ -73,6 +73,7 @@ InitHeapAccessStatistics()
stats->global_insert = 0; stats->global_insert = 0;
stats->global_delete = 0; stats->global_delete = 0;
stats->global_replace = 0; stats->global_replace = 0;
stats->global_mark4update = 0;
stats->global_markpos = 0; stats->global_markpos = 0;
stats->global_restrpos = 0; stats->global_restrpos = 0;
stats->global_BufferGetRelation = 0; stats->global_BufferGetRelation = 0;
...@@ -94,6 +95,7 @@ InitHeapAccessStatistics() ...@@ -94,6 +95,7 @@ InitHeapAccessStatistics()
stats->local_insert = 0; stats->local_insert = 0;
stats->local_delete = 0; stats->local_delete = 0;
stats->local_replace = 0; stats->local_replace = 0;
stats->local_mark4update = 0;
stats->local_markpos = 0; stats->local_markpos = 0;
stats->local_restrpos = 0; stats->local_restrpos = 0;
stats->local_BufferGetRelation = 0; stats->local_BufferGetRelation = 0;
...@@ -157,6 +159,7 @@ ResetHeapAccessStatistics() ...@@ -157,6 +159,7 @@ ResetHeapAccessStatistics()
stats->local_insert = 0; stats->local_insert = 0;
stats->local_delete = 0; stats->local_delete = 0;
stats->local_replace = 0; stats->local_replace = 0;
stats->local_mark4update = 0;
stats->local_markpos = 0; stats->local_markpos = 0;
stats->local_restrpos = 0; stats->local_restrpos = 0;
stats->local_BufferGetRelation = 0; stats->local_BufferGetRelation = 0;
...@@ -274,6 +277,9 @@ PrintHeapAccessStatistics(HeapAccessStatistics stats) ...@@ -274,6 +277,9 @@ PrintHeapAccessStatistics(HeapAccessStatistics stats)
printf("local/global_replace: %6d/%6d\n", printf("local/global_replace: %6d/%6d\n",
stats->local_replace, stats->global_replace); stats->local_replace, stats->global_replace);
printf("local/global_mark4update: %6d/%6d\n",
stats->local_mark4update, stats->global_mark4update);
printf("local/global_markpos: %6d/%6d\n", printf("local/global_markpos: %6d/%6d\n",
stats->local_markpos, stats->global_markpos); stats->local_markpos, stats->global_markpos);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.28 1998/10/02 16:27:43 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.29 1998/12/15 12:45:15 vadim Exp $
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
* index_open - open an index relation by relationId * index_open - open an index relation by relationId
...@@ -225,7 +225,7 @@ index_beginscan(Relation relation, ...@@ -225,7 +225,7 @@ index_beginscan(Relation relation,
RELATION_CHECKS; RELATION_CHECKS;
GET_REL_PROCEDURE(beginscan, ambeginscan); GET_REL_PROCEDURE(beginscan, ambeginscan);
RelationSetRIntentLock(relation); LockRelation(relation, AccessShareLock);
scandesc = (IndexScanDesc) scandesc = (IndexScanDesc)
fmgr(procedure, relation, scanFromEnd, numberOfKeys, key); fmgr(procedure, relation, scanFromEnd, numberOfKeys, key);
...@@ -262,7 +262,7 @@ index_endscan(IndexScanDesc scan) ...@@ -262,7 +262,7 @@ index_endscan(IndexScanDesc scan)
fmgr(procedure, scan); fmgr(procedure, scan);
RelationUnsetRIntentLock(scan->relation); UnlockRelation(scan->relation, AccessShareLock);
} }
/* ---------------- /* ----------------
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.31 1998/11/27 19:51:40 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.32 1998/12/15 12:45:20 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <storage/bufpage.h> #include <storage/bufpage.h>
#include <access/nbtree.h> #include <access/nbtree.h>
#include <access/heapam.h> #include <access/heapam.h>
#include <access/xact.h>
#include <storage/bufmgr.h> #include <storage/bufmgr.h>
#include <fmgr.h> #include <fmgr.h>
...@@ -67,6 +68,8 @@ _bt_doinsert(Relation rel, BTItem btitem, bool index_is_unique, Relation heapRel ...@@ -67,6 +68,8 @@ _bt_doinsert(Relation rel, BTItem btitem, bool index_is_unique, Relation heapRel
/* trade in our read lock for a write lock */ /* trade in our read lock for a write lock */
_bt_relbuf(rel, buf, BT_READ); _bt_relbuf(rel, buf, BT_READ);
l1:
buf = _bt_getbuf(rel, blkno, BT_WRITE); buf = _bt_getbuf(rel, blkno, BT_WRITE);
/* /*
...@@ -120,9 +123,25 @@ _bt_doinsert(Relation rel, BTItem btitem, bool index_is_unique, Relation heapRel ...@@ -120,9 +123,25 @@ _bt_doinsert(Relation rel, BTItem btitem, bool index_is_unique, Relation heapRel
{ /* they're equal */ { /* they're equal */
btitem = (BTItem) PageGetItem(page, PageGetItemId(page, offset)); btitem = (BTItem) PageGetItem(page, PageGetItemId(page, offset));
htup.t_self = btitem->bti_itup.t_tid; htup.t_self = btitem->bti_itup.t_tid;
heap_fetch(heapRel, SnapshotSelf, &htup, &buffer); heap_fetch(heapRel, SnapshotDirty, &htup, &buffer);
if (htup.t_data != NULL) if (htup.t_data != NULL) /* it is a duplicate */
{ /* it is a duplicate */ {
TransactionId xwait =
(TransactionIdIsValid(SnapshotDirty->xmin)) ?
SnapshotDirty->xmin : SnapshotDirty->xmax;
/*
* If this tuple is being updated by other transaction
* then we have to wait for its commit/abort.
*/
if (TransactionIdIsValid(xwait))
{
if (nbuf != InvalidBuffer)
_bt_relbuf(rel, nbuf, BT_READ);
_bt_relbuf(rel, buf, BT_WRITE);
XactLockTableWait(xwait);
goto l1; /* continue from the begin */
}
elog(ERROR, "Cannot insert a duplicate key into a unique index"); elog(ERROR, "Cannot insert a duplicate key into a unique index");
} }
/* htup null so no buffer to release */ /* htup null so no buffer to release */
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.16 1998/09/01 03:21:14 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.17 1998/12/15 12:45:23 vadim Exp $
* *
* NOTES * NOTES
* Postgres btree pages look like ordinary relation pages. The opaque * Postgres btree pages look like ordinary relation pages. The opaque
...@@ -93,7 +93,7 @@ _bt_metapinit(Relation rel) ...@@ -93,7 +93,7 @@ _bt_metapinit(Relation rel)
/* can't be sharing this with anyone, now... */ /* can't be sharing this with anyone, now... */
if (USELOCKING) if (USELOCKING)
RelationSetLockForWrite(rel); LockRelation(rel, AccessExclusiveLock);
if ((nblocks = RelationGetNumberOfBlocks(rel)) != 0) if ((nblocks = RelationGetNumberOfBlocks(rel)) != 0)
{ {
...@@ -120,7 +120,7 @@ _bt_metapinit(Relation rel) ...@@ -120,7 +120,7 @@ _bt_metapinit(Relation rel)
/* all done */ /* all done */
if (USELOCKING) if (USELOCKING)
RelationUnsetLockForWrite(rel); UnlockRelation(rel, AccessExclusiveLock);
} }
#ifdef NOT_USED #ifdef NOT_USED
...@@ -571,32 +571,26 @@ _bt_getstackbuf(Relation rel, BTStack stack, int access) ...@@ -571,32 +571,26 @@ _bt_getstackbuf(Relation rel, BTStack stack, int access)
static void static void
_bt_setpagelock(Relation rel, BlockNumber blkno, int access) _bt_setpagelock(Relation rel, BlockNumber blkno, int access)
{ {
ItemPointerData iptr;
if (USELOCKING) if (USELOCKING)
{ {
ItemPointerSet(&iptr, blkno, P_HIKEY);
if (access == BT_WRITE) if (access == BT_WRITE)
RelationSetSingleWLockPage(rel, &iptr); LockPage(rel, blkno, ExclusiveLock);
else else
RelationSetSingleRLockPage(rel, &iptr); LockPage(rel, blkno, ShareLock);
} }
} }
static void static void
_bt_unsetpagelock(Relation rel, BlockNumber blkno, int access) _bt_unsetpagelock(Relation rel, BlockNumber blkno, int access)
{ {
ItemPointerData iptr;
if (USELOCKING) if (USELOCKING)
{ {
ItemPointerSet(&iptr, blkno, P_HIKEY);
if (access == BT_WRITE) if (access == BT_WRITE)
RelationUnsetSingleWLockPage(rel, &iptr); UnlockPage(rel, blkno, ExclusiveLock);
else else
RelationUnsetSingleRLockPage(rel, &iptr); UnlockPage(rel, blkno, ShareLock);
} }
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.29 1998/11/27 19:51:41 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.30 1998/12/15 12:45:25 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -107,9 +107,6 @@ rtbuild(Relation heap, ...@@ -107,9 +107,6 @@ rtbuild(Relation heap,
initRtstate(&rtState, index); initRtstate(&rtState, index);
/* rtrees only know how to do stupid locking now */
RelationSetLockForWrite(index);
pred = predInfo->pred; pred = predInfo->pred;
oldPred = predInfo->oldPred; oldPred = predInfo->oldPred;
...@@ -250,7 +247,6 @@ rtbuild(Relation heap, ...@@ -250,7 +247,6 @@ rtbuild(Relation heap,
/* okay, all heap tuples are indexed */ /* okay, all heap tuples are indexed */
heap_endscan(scan); heap_endscan(scan);
RelationUnsetLockForWrite(index);
if (pred != NULL || oldPred != NULL) if (pred != NULL || oldPred != NULL)
{ {
...@@ -308,10 +304,14 @@ rtinsert(Relation r, Datum *datum, char *nulls, ItemPointer ht_ctid, Relation he ...@@ -308,10 +304,14 @@ rtinsert(Relation r, Datum *datum, char *nulls, ItemPointer ht_ctid, Relation he
itup->t_tid = *ht_ctid; itup->t_tid = *ht_ctid;
initRtstate(&rtState, r); initRtstate(&rtState, r);
/*
* Notes in ExecUtils:ExecOpenIndices()
*
RelationSetLockForWrite(r); RelationSetLockForWrite(r);
*/
res = rtdoinsert(r, itup, &rtState); res = rtdoinsert(r, itup, &rtState);
/* XXX two-phase locking -- don't unlock the relation until EOT */
return res; return res;
} }
...@@ -946,8 +946,12 @@ rtdelete(Relation r, ItemPointer tid) ...@@ -946,8 +946,12 @@ rtdelete(Relation r, ItemPointer tid)
Buffer buf; Buffer buf;
Page page; Page page;
/* must write-lock on delete */ /*
* Notes in ExecUtils:ExecOpenIndices()
* Also note that only vacuum deletes index tuples now...
*
RelationSetLockForWrite(r); RelationSetLockForWrite(r);
*/
blkno = ItemPointerGetBlockNumber(tid); blkno = ItemPointerGetBlockNumber(tid);
offnum = ItemPointerGetOffsetNumber(tid); offnum = ItemPointerGetOffsetNumber(tid);
...@@ -963,7 +967,6 @@ rtdelete(Relation r, ItemPointer tid) ...@@ -963,7 +967,6 @@ rtdelete(Relation r, ItemPointer tid)
WriteBuffer(buf); WriteBuffer(buf);
/* XXX -- two-phase locking, don't release the write lock */
return (char *) NULL; return (char *) NULL;
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.19 1998/09/01 04:27:12 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.20 1998/12/15 12:45:29 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -66,7 +66,12 @@ rtbeginscan(Relation r, ...@@ -66,7 +66,12 @@ rtbeginscan(Relation r,
{ {
IndexScanDesc s; IndexScanDesc s;
/*
* Let index_beginscan does its work...
*
RelationSetLockForRead(r); RelationSetLockForRead(r);
*/
s = RelationGetIndexScan(r, fromEnd, nkeys, key); s = RelationGetIndexScan(r, fromEnd, nkeys, key);
rtregscan(s); rtregscan(s);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/transam.c,v 1.19 1998/09/01 04:27:15 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/transam/transam.c,v 1.20 1998/12/15 12:45:30 vadim Exp $
* *
* NOTES * NOTES
* This file contains the high level access-method interface to the * This file contains the high level access-method interface to the
...@@ -172,8 +172,12 @@ TransactionLogTest(TransactionId transactionId, /* transaction id to test */ ...@@ -172,8 +172,12 @@ TransactionLogTest(TransactionId transactionId, /* transaction id to test */
if (!fail) if (!fail)
{ {
TransactionIdStore(transactionId, &cachedTestXid); /* must not cache status of running xaction !!! */
cachedTestXidStatus = xidstatus; if (xidstatus != XID_INPROGRESS)
{
TransactionIdStore(transactionId, &cachedTestXid);
cachedTestXidStatus = xidstatus;
}
return (bool) return (bool)
(status == xidstatus); (status == xidstatus);
} }
...@@ -219,11 +223,14 @@ TransactionLogUpdate(TransactionId transactionId, /* trans id to update */ ...@@ -219,11 +223,14 @@ TransactionLogUpdate(TransactionId transactionId, /* trans id to update */
status, status,
&fail); &fail);
/* ---------------- /*
* update (invalidate) our single item TransactionLogTest cache. * update (invalidate) our single item TransactionLogTest cache.
* ---------------- *
*/
if (status != XID_COMMIT) if (status != XID_COMMIT)
*
* What's the hell ?! Why != XID_COMMIT ?!
*/
if (status != XID_INPROGRESS)
{ {
TransactionIdStore(transactionId, &cachedTestXid); TransactionIdStore(transactionId, &cachedTestXid);
cachedTestXidStatus = status; cachedTestXidStatus = status;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/Attic/transsup.c,v 1.17 1998/09/01 04:27:16 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/transam/Attic/transsup.c,v 1.18 1998/12/15 12:45:33 vadim Exp $
* *
* NOTES * NOTES
* This file contains support functions for the high * This file contains support functions for the high
...@@ -289,18 +289,12 @@ TransBlockNumberGetXidStatus(Relation relation, ...@@ -289,18 +289,12 @@ TransBlockNumberGetXidStatus(Relation relation,
XidStatus xstatus; /* recorded status of xid */ XidStatus xstatus; /* recorded status of xid */
bool localfail; /* bool used if failP = NULL */ bool localfail; /* bool used if failP = NULL */
/* ----------------
* SOMEDAY place a read lock on the log relation
* That someday is today 5 Aug 1991 -mer
* ----------------
*/
RelationSetLockForRead(relation);
/* ---------------- /* ----------------
* get the page containing the transaction information * get the page containing the transaction information
* ---------------- * ----------------
*/ */
buffer = ReadBuffer(relation, blockNumber); buffer = ReadBuffer(relation, blockNumber);
LockBuffer(buffer, BUFFER_LOCK_SHARE);
block = BufferGetBlock(buffer); block = BufferGetBlock(buffer);
/* ---------------- /* ----------------
...@@ -318,14 +312,9 @@ TransBlockNumberGetXidStatus(Relation relation, ...@@ -318,14 +312,9 @@ TransBlockNumberGetXidStatus(Relation relation,
* release the buffer and return the status * release the buffer and return the status
* ---------------- * ----------------
*/ */
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
ReleaseBuffer(buffer); ReleaseBuffer(buffer);
/* ----------------
* SOMEDAY release our lock on the log relation
* ----------------
*/
RelationUnsetLockForRead(relation);
return return
xstatus; xstatus;
} }
...@@ -345,19 +334,12 @@ TransBlockNumberSetXidStatus(Relation relation, ...@@ -345,19 +334,12 @@ TransBlockNumberSetXidStatus(Relation relation,
Block block; /* block containing xstatus */ Block block; /* block containing xstatus */
bool localfail; /* bool used if failP = NULL */ bool localfail; /* bool used if failP = NULL */
/* ----------------
* SOMEDAY gain exclusive access to the log relation
*
* That someday is today 5 Aug 1991 -mer
* ----------------
*/
RelationSetLockForWrite(relation);
/* ---------------- /* ----------------
* get the block containing the transaction status * get the block containing the transaction status
* ---------------- * ----------------
*/ */
buffer = ReadBuffer(relation, blockNumber); buffer = ReadBuffer(relation, blockNumber);
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
block = BufferGetBlock(buffer); block = BufferGetBlock(buffer);
/* ---------------- /* ----------------
...@@ -372,16 +354,11 @@ TransBlockNumberSetXidStatus(Relation relation, ...@@ -372,16 +354,11 @@ TransBlockNumberSetXidStatus(Relation relation,
TransBlockSetXidStatus(block, xid, xstatus); TransBlockSetXidStatus(block, xid, xstatus);
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
if ((*failP) == false) if ((*failP) == false)
WriteBuffer(buffer); WriteBuffer(buffer);
else else
ReleaseBuffer(buffer); ReleaseBuffer(buffer);
/* ----------------
* SOMEDAY release our lock on the log relation
* ----------------
*/
RelationUnsetLockForWrite(relation);
} }
/* -------------------------------- /* --------------------------------
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.25 1998/10/08 18:29:15 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.26 1998/12/15 12:45:35 vadim Exp $
* *
* NOTES * NOTES
* Transaction aborts can now occur two ways: * Transaction aborts can now occur two ways:
...@@ -194,6 +194,8 @@ TransactionStateData CurrentTransactionStateData = { ...@@ -194,6 +194,8 @@ TransactionStateData CurrentTransactionStateData = {
TransactionState CurrentTransactionState = TransactionState CurrentTransactionState =
&CurrentTransactionStateData; &CurrentTransactionStateData;
int XactIsoLevel = XACT_SERIALIZED;
/* ---------------- /* ----------------
* info returned when the system is disabled * info returned when the system is disabled
* *
...@@ -816,6 +818,8 @@ StartTransaction() ...@@ -816,6 +818,8 @@ StartTransaction()
*/ */
GetNewTransactionId(&(s->transactionIdData)); GetNewTransactionId(&(s->transactionIdData));
XactLockTableInsert(s->transactionIdData);
/* ---------------- /* ----------------
* initialize current transaction state fields * initialize current transaction state fields
* ---------------- * ----------------
...@@ -966,6 +970,7 @@ AbortTransaction() ...@@ -966,6 +970,7 @@ AbortTransaction()
* do abort processing * do abort processing
* ---------------- * ----------------
*/ */
UnlockBuffers();
AtAbort_Notify(); AtAbort_Notify();
CloseSequences(); CloseSequences();
AtEOXact_portals(); AtEOXact_portals();
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.17 1998/11/27 19:51:46 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.18 1998/12/15 12:45:39 vadim Exp $
* *
* NOTES * NOTES
* See acl.h. * See acl.h.
...@@ -162,7 +162,7 @@ ChangeAcl(char *relname, ...@@ -162,7 +162,7 @@ ChangeAcl(char *relname,
tuple = heap_modifytuple(tuple, relation, values, nulls, replaces); tuple = heap_modifytuple(tuple, relation, values, nulls, replaces);
/* XXX handle index on pg_class? */ /* XXX handle index on pg_class? */
setheapoverride(true); setheapoverride(true);
heap_replace(relation, &tuple->t_self, tuple); heap_replace(relation, &tuple->t_self, tuple, NULL);
setheapoverride(false); setheapoverride(false);
/* keep the catalog indices up to date */ /* keep the catalog indices up to date */
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.69 1998/12/14 05:18:37 scrappy Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.70 1998/12/15 12:45:40 vadim Exp $
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
* heap_create() - Create an uncataloged heap relation * heap_create() - Create an uncataloged heap relation
...@@ -929,7 +929,7 @@ RelationRemoveInheritance(Relation relation) ...@@ -929,7 +929,7 @@ RelationRemoveInheritance(Relation relation)
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0))) while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
{ {
heap_delete(catalogRelation, &tuple->t_self); heap_delete(catalogRelation, &tuple->t_self, NULL);
found = true; found = true;
} }
...@@ -951,7 +951,7 @@ RelationRemoveInheritance(Relation relation) ...@@ -951,7 +951,7 @@ RelationRemoveInheritance(Relation relation)
&entry); &entry);
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0))) while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
heap_delete(catalogRelation, &tuple->t_self); heap_delete(catalogRelation, &tuple->t_self, NULL);
heap_endscan(scan); heap_endscan(scan);
heap_close(catalogRelation); heap_close(catalogRelation);
...@@ -1020,7 +1020,7 @@ DeletePgRelationTuple(Relation rel) ...@@ -1020,7 +1020,7 @@ DeletePgRelationTuple(Relation rel)
* delete the relation tuple from pg_class, and finish up. * delete the relation tuple from pg_class, and finish up.
* ---------------- * ----------------
*/ */
heap_delete(pg_class_desc, &tup->t_self); heap_delete(pg_class_desc, &tup->t_self, NULL);
pfree(tup); pfree(tup);
heap_close(pg_class_desc); heap_close(pg_class_desc);
...@@ -1048,7 +1048,7 @@ DeletePgAttributeTuples(Relation rel) ...@@ -1048,7 +1048,7 @@ DeletePgAttributeTuples(Relation rel)
* Get a write lock _before_ getting the read lock in the scan * Get a write lock _before_ getting the read lock in the scan
* ---------------- * ----------------
*/ */
RelationSetLockForWrite(pg_attribute_desc); LockRelation(pg_attribute_desc, AccessExclusiveLock);
for (attnum = FirstLowInvalidHeapAttributeNumber + 1; for (attnum = FirstLowInvalidHeapAttributeNumber + 1;
attnum <= rel->rd_att->natts; attnum <= rel->rd_att->natts;
...@@ -1059,7 +1059,7 @@ DeletePgAttributeTuples(Relation rel) ...@@ -1059,7 +1059,7 @@ DeletePgAttributeTuples(Relation rel)
Int16GetDatum(attnum), Int16GetDatum(attnum),
0, 0))) 0, 0)))
{ {
heap_delete(pg_attribute_desc, &tup->t_self); heap_delete(pg_attribute_desc, &tup->t_self, NULL);
pfree(tup); pfree(tup);
} }
} }
...@@ -1068,7 +1068,7 @@ DeletePgAttributeTuples(Relation rel) ...@@ -1068,7 +1068,7 @@ DeletePgAttributeTuples(Relation rel)
* Release the write lock * Release the write lock
* ---------------- * ----------------
*/ */
RelationUnsetLockForWrite(pg_attribute_desc); UnlockRelation(pg_attribute_desc, AccessExclusiveLock);
heap_close(pg_attribute_desc); heap_close(pg_attribute_desc);
} }
...@@ -1183,7 +1183,7 @@ DeletePgTypeTuple(Relation rel) ...@@ -1183,7 +1183,7 @@ DeletePgTypeTuple(Relation rel)
* we release the read lock on pg_type. -mer 13 Aug 1991 * we release the read lock on pg_type. -mer 13 Aug 1991
* ---------------- * ----------------
*/ */
heap_delete(pg_type_desc, &tup->t_self); heap_delete(pg_type_desc, &tup->t_self, NULL);
heap_endscan(pg_type_scan); heap_endscan(pg_type_scan);
heap_close(pg_type_desc); heap_close(pg_type_desc);
...@@ -1209,7 +1209,7 @@ heap_destroy_with_catalog(char *relname) ...@@ -1209,7 +1209,7 @@ heap_destroy_with_catalog(char *relname)
if (rel == NULL) if (rel == NULL)
elog(ERROR, "Relation %s Does Not Exist!", relname); elog(ERROR, "Relation %s Does Not Exist!", relname);
RelationSetLockForWrite(rel); LockRelation(rel, AccessExclusiveLock);
rid = rel->rd_id; rid = rel->rd_id;
/* ---------------- /* ----------------
...@@ -1288,7 +1288,7 @@ heap_destroy_with_catalog(char *relname) ...@@ -1288,7 +1288,7 @@ heap_destroy_with_catalog(char *relname)
rel->rd_tmpunlinked = TRUE; rel->rd_tmpunlinked = TRUE;
RelationUnsetLockForWrite(rel); UnlockRelation(rel, AccessExclusiveLock);
heap_close(rel); heap_close(rel);
...@@ -1608,16 +1608,16 @@ RemoveAttrDefault(Relation rel) ...@@ -1608,16 +1608,16 @@ RemoveAttrDefault(Relation rel)
ScanKeyEntryInitialize(&key, 0, Anum_pg_attrdef_adrelid, ScanKeyEntryInitialize(&key, 0, Anum_pg_attrdef_adrelid,
F_OIDEQ, rel->rd_id); F_OIDEQ, rel->rd_id);
RelationSetLockForWrite(adrel); LockRelation(adrel, AccessExclusiveLock);
adscan = heap_beginscan(adrel, 0, SnapshotNow, 1, &key); adscan = heap_beginscan(adrel, 0, SnapshotNow, 1, &key);
while (HeapTupleIsValid(tup = heap_getnext(adscan, 0))) while (HeapTupleIsValid(tup = heap_getnext(adscan, 0)))
heap_delete(adrel, &tup->t_self); heap_delete(adrel, &tup->t_self, NULL);
heap_endscan(adscan); heap_endscan(adscan);
RelationUnsetLockForWrite(adrel); UnlockRelation(adrel, AccessExclusiveLock);
heap_close(adrel); heap_close(adrel);
} }
...@@ -1635,16 +1635,16 @@ RemoveRelCheck(Relation rel) ...@@ -1635,16 +1635,16 @@ RemoveRelCheck(Relation rel)
ScanKeyEntryInitialize(&key, 0, Anum_pg_relcheck_rcrelid, ScanKeyEntryInitialize(&key, 0, Anum_pg_relcheck_rcrelid,
F_OIDEQ, rel->rd_id); F_OIDEQ, rel->rd_id);
RelationSetLockForWrite(rcrel); LockRelation(rcrel, AccessExclusiveLock);
rcscan = heap_beginscan(rcrel, 0, SnapshotNow, 1, &key); rcscan = heap_beginscan(rcrel, 0, SnapshotNow, 1, &key);
while (HeapTupleIsValid(tup = heap_getnext(rcscan, 0))) while (HeapTupleIsValid(tup = heap_getnext(rcscan, 0)))
heap_delete(rcrel, &tup->t_self); heap_delete(rcrel, &tup->t_self, NULL);
heap_endscan(rcscan); heap_endscan(rcscan);
RelationUnsetLockForWrite(rcrel); UnlockRelation(rcrel, AccessExclusiveLock);
heap_close(rcrel); heap_close(rcrel);
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.65 1998/12/13 04:37:50 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.66 1998/12/15 12:45:43 vadim Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -913,7 +913,7 @@ UpdateIndexPredicate(Oid indexoid, Node *oldPred, Node *predicate) ...@@ -913,7 +913,7 @@ UpdateIndexPredicate(Oid indexoid, Node *oldPred, Node *predicate)
newtup = heap_modifytuple(tuple, pg_index, values, nulls, replace); newtup = heap_modifytuple(tuple, pg_index, values, nulls, replace);
heap_replace(pg_index, &newtup->t_self, newtup); heap_replace(pg_index, &newtup->t_self, newtup, NULL);
pfree(newtup); pfree(newtup);
heap_close(pg_index); heap_close(pg_index);
...@@ -1039,15 +1039,11 @@ index_create(char *heapRelationName, ...@@ -1039,15 +1039,11 @@ index_create(char *heapRelationName,
heapRelation = heap_open(heapoid); heapRelation = heap_open(heapoid);
/* ---------------- /*
* write lock heap to guarantee exclusive access * Only SELECT ... FOR UPDATE are allowed
* ----------------
RelationSetLockForWrite(heapRelation);
* ^^^^^
* Does it have any sense ? - vadim 10/27/97
*/ */
RelationSetLockForRead(heapRelation); LockRelation(heapRelation, ShareLock);
/* ---------------- /* ----------------
* construct new tuple descriptor * construct new tuple descriptor
...@@ -1195,7 +1191,7 @@ index_destroy(Oid indexId) ...@@ -1195,7 +1191,7 @@ index_destroy(Oid indexId)
AssertState(HeapTupleIsValid(tuple)); AssertState(HeapTupleIsValid(tuple));
heap_delete(relationRelation, &tuple->t_self); heap_delete(relationRelation, &tuple->t_self, NULL);
pfree(tuple); pfree(tuple);
heap_close(relationRelation); heap_close(relationRelation);
...@@ -1212,7 +1208,7 @@ index_destroy(Oid indexId) ...@@ -1212,7 +1208,7 @@ index_destroy(Oid indexId)
Int16GetDatum(attnum), Int16GetDatum(attnum),
0, 0))) 0, 0)))
{ {
heap_delete(attributeRelation, &tuple->t_self); heap_delete(attributeRelation, &tuple->t_self, NULL);
pfree(tuple); pfree(tuple);
attnum++; attnum++;
} }
...@@ -1232,7 +1228,7 @@ index_destroy(Oid indexId) ...@@ -1232,7 +1228,7 @@ index_destroy(Oid indexId)
indexRelation = heap_openr(IndexRelationName); indexRelation = heap_openr(IndexRelationName);
heap_delete(indexRelation, &tuple->t_self); heap_delete(indexRelation, &tuple->t_self, NULL);
pfree(tuple); pfree(tuple);
heap_close(indexRelation); heap_close(indexRelation);
...@@ -1424,7 +1420,7 @@ UpdateStats(Oid relid, long reltuples, bool hasindex) ...@@ -1424,7 +1420,7 @@ UpdateStats(Oid relid, long reltuples, bool hasindex)
values[Anum_pg_class_relhasindex - 1] = CharGetDatum(hasindex); values[Anum_pg_class_relhasindex - 1] = CharGetDatum(hasindex);
newtup = heap_modifytuple(tuple, pg_class, values, nulls, replace); newtup = heap_modifytuple(tuple, pg_class, values, nulls, replace);
heap_replace(pg_class, &tuple->t_self, newtup); heap_replace(pg_class, &tuple->t_self, newtup, NULL);
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs); CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
CatalogIndexInsert(idescs, Num_pg_class_indices, pg_class, newtup); CatalogIndexInsert(idescs, Num_pg_class_indices, pg_class, newtup);
CatalogCloseIndices(Num_pg_class_indices, idescs); CatalogCloseIndices(Num_pg_class_indices, idescs);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.30 1998/11/27 19:51:50 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.31 1998/12/15 12:45:45 vadim Exp $
* *
* NOTES * NOTES
* these routines moved here from commands/define.c and somewhat cleaned up. * these routines moved here from commands/define.c and somewhat cleaned up.
...@@ -711,7 +711,7 @@ OperatorDef(char *operatorName, ...@@ -711,7 +711,7 @@ OperatorDef(char *operatorName,
replaces); replaces);
setheapoverride(true); setheapoverride(true);
heap_replace(pg_operator_desc, &tup->t_self, tup); heap_replace(pg_operator_desc, &tup->t_self, tup, NULL);
setheapoverride(false); setheapoverride(false);
} }
else else
...@@ -830,7 +830,7 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId) ...@@ -830,7 +830,7 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId)
replaces); replaces);
setheapoverride(true); setheapoverride(true);
heap_replace(pg_operator_desc, &tup->t_self, tup); heap_replace(pg_operator_desc, &tup->t_self, tup, NULL);
setheapoverride(false); setheapoverride(false);
} }
...@@ -855,7 +855,7 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId) ...@@ -855,7 +855,7 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId)
replaces); replaces);
setheapoverride(true); setheapoverride(true);
heap_replace(pg_operator_desc, &tup->t_self, tup); heap_replace(pg_operator_desc, &tup->t_self, tup, NULL);
setheapoverride(false); setheapoverride(false);
values[Anum_pg_operator_oprcom - 1] = (Datum) NULL; values[Anum_pg_operator_oprcom - 1] = (Datum) NULL;
...@@ -884,7 +884,7 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId) ...@@ -884,7 +884,7 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId)
replaces); replaces);
setheapoverride(true); setheapoverride(true);
heap_replace(pg_operator_desc, &tup->t_self, tup); heap_replace(pg_operator_desc, &tup->t_self, tup, NULL);
setheapoverride(false); setheapoverride(false);
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.31 1998/11/27 19:51:51 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.32 1998/12/15 12:45:47 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -459,7 +459,7 @@ TypeCreate(char *typeName, ...@@ -459,7 +459,7 @@ TypeCreate(char *typeName,
* when the heap_insert() or heap_replace() is called. * when the heap_insert() or heap_replace() is called.
* ----------------- * -----------------
*/ */
RelationSetLockForWrite(pg_type_desc); LockRelation(pg_type_desc, AccessExclusiveLock);
typeKey[0].sk_argument = PointerGetDatum(typeName); typeKey[0].sk_argument = PointerGetDatum(typeName);
pg_type_scan = heap_beginscan(pg_type_desc, pg_type_scan = heap_beginscan(pg_type_desc,
...@@ -484,7 +484,7 @@ TypeCreate(char *typeName, ...@@ -484,7 +484,7 @@ TypeCreate(char *typeName,
replaces); replaces);
setheapoverride(true); setheapoverride(true);
heap_replace(pg_type_desc, &tup->t_self, tup); heap_replace(pg_type_desc, &tup->t_self, tup, NULL);
setheapoverride(false); setheapoverride(false);
typeObjectId = tup->t_data->t_oid; typeObjectId = tup->t_data->t_oid;
...@@ -516,7 +516,7 @@ TypeCreate(char *typeName, ...@@ -516,7 +516,7 @@ TypeCreate(char *typeName,
CatalogIndexInsert(idescs, Num_pg_type_indices, pg_type_desc, tup); CatalogIndexInsert(idescs, Num_pg_type_indices, pg_type_desc, tup);
CatalogCloseIndices(Num_pg_type_indices, idescs); CatalogCloseIndices(Num_pg_type_indices, idescs);
} }
RelationUnsetLockForWrite(pg_type_desc); UnlockRelation(pg_type_desc, AccessExclusiveLock);
heap_close(pg_type_desc); heap_close(pg_type_desc);
return typeObjectId; return typeObjectId;
...@@ -561,7 +561,7 @@ TypeRename(char *oldTypeName, char *newTypeName) ...@@ -561,7 +561,7 @@ TypeRename(char *oldTypeName, char *newTypeName)
namestrcpy(&(((Form_pg_type) GETSTRUCT(oldtup))->typname), newTypeName); namestrcpy(&(((Form_pg_type) GETSTRUCT(oldtup))->typname), newTypeName);
setheapoverride(true); setheapoverride(true);
heap_replace(pg_type_desc, &oldtup->t_self, oldtup); heap_replace(pg_type_desc, &oldtup->t_self, oldtup, NULL);
setheapoverride(false); setheapoverride(false);
/* update the system catalog indices */ /* update the system catalog indices */
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.42 1998/11/27 19:51:53 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.43 1998/12/15 12:45:50 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -218,7 +218,7 @@ Async_Listen(char *relname, int pid) ...@@ -218,7 +218,7 @@ Async_Listen(char *relname, int pid)
TPRINTF(TRACE_NOTIFY, "Async_Listen: %s", relname); TPRINTF(TRACE_NOTIFY, "Async_Listen: %s", relname);
lRel = heap_openr(ListenerRelationName); lRel = heap_openr(ListenerRelationName);
RelationSetLockForWrite(lRel); LockRelation(lRel, AccessExclusiveLock);
tdesc = RelationGetDescr(lRel); tdesc = RelationGetDescr(lRel);
/* Detect whether we are already listening on this relname */ /* Detect whether we are already listening on this relname */
...@@ -242,7 +242,7 @@ Async_Listen(char *relname, int pid) ...@@ -242,7 +242,7 @@ Async_Listen(char *relname, int pid)
if (alreadyListener) if (alreadyListener)
{ {
elog(NOTICE, "Async_Listen: We are already listening on %s", relname); elog(NOTICE, "Async_Listen: We are already listening on %s", relname);
RelationUnsetLockForWrite(lRel); UnlockRelation(lRel, AccessExclusiveLock);
heap_close(lRel); heap_close(lRel);
return; return;
} }
...@@ -267,7 +267,7 @@ Async_Listen(char *relname, int pid) ...@@ -267,7 +267,7 @@ Async_Listen(char *relname, int pid)
heap_insert(lRel, newtup); heap_insert(lRel, newtup);
pfree(newtup); pfree(newtup);
RelationUnsetLockForWrite(lRel); UnlockRelation(lRel, AccessExclusiveLock);
heap_close(lRel); heap_close(lRel);
/* /*
...@@ -320,9 +320,9 @@ Async_Unlisten(char *relname, int pid) ...@@ -320,9 +320,9 @@ Async_Unlisten(char *relname, int pid)
if (lTuple != NULL) if (lTuple != NULL)
{ {
lRel = heap_openr(ListenerRelationName); lRel = heap_openr(ListenerRelationName);
RelationSetLockForWrite(lRel); LockRelation(lRel, AccessExclusiveLock);
heap_delete(lRel, &lTuple->t_self); heap_delete(lRel, &lTuple->t_self, NULL);
RelationUnsetLockForWrite(lRel); UnlockRelation(lRel, AccessExclusiveLock);
heap_close(lRel); heap_close(lRel);
} }
/* We do not complain about unlistening something not being listened; /* We do not complain about unlistening something not being listened;
...@@ -358,7 +358,7 @@ Async_UnlistenAll() ...@@ -358,7 +358,7 @@ Async_UnlistenAll()
TPRINTF(TRACE_NOTIFY, "Async_UnlistenAll"); TPRINTF(TRACE_NOTIFY, "Async_UnlistenAll");
lRel = heap_openr(ListenerRelationName); lRel = heap_openr(ListenerRelationName);
RelationSetLockForWrite(lRel); LockRelation(lRel, AccessExclusiveLock);
tdesc = RelationGetDescr(lRel); tdesc = RelationGetDescr(lRel);
/* Find and delete all entries with my listenerPID */ /* Find and delete all entries with my listenerPID */
...@@ -369,10 +369,10 @@ Async_UnlistenAll() ...@@ -369,10 +369,10 @@ Async_UnlistenAll()
sRel = heap_beginscan(lRel, 0, SnapshotNow, 1, key); sRel = heap_beginscan(lRel, 0, SnapshotNow, 1, key);
while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0))) while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0)))
heap_delete(lRel, &lTuple->t_self); heap_delete(lRel, &lTuple->t_self, NULL);
heap_endscan(sRel); heap_endscan(sRel);
RelationUnsetLockForWrite(lRel); UnlockRelation(lRel, AccessExclusiveLock);
heap_close(lRel); heap_close(lRel);
} }
...@@ -463,7 +463,7 @@ AtCommit_Notify() ...@@ -463,7 +463,7 @@ AtCommit_Notify()
TPRINTF(TRACE_NOTIFY, "AtCommit_Notify"); TPRINTF(TRACE_NOTIFY, "AtCommit_Notify");
lRel = heap_openr(ListenerRelationName); lRel = heap_openr(ListenerRelationName);
RelationSetLockForWrite(lRel); LockRelation(lRel, AccessExclusiveLock);
tdesc = RelationGetDescr(lRel); tdesc = RelationGetDescr(lRel);
sRel = heap_beginscan(lRel, 0, SnapshotNow, 0, (ScanKey) NULL); sRel = heap_beginscan(lRel, 0, SnapshotNow, 0, (ScanKey) NULL);
...@@ -516,7 +516,7 @@ AtCommit_Notify() ...@@ -516,7 +516,7 @@ AtCommit_Notify()
* but as far as I can see we should just do it for any * but as far as I can see we should just do it for any
* failure (certainly at least for EPERM too...) * failure (certainly at least for EPERM too...)
*/ */
heap_delete(lRel, &lTuple->t_self); heap_delete(lRel, &lTuple->t_self, NULL);
} }
else else
#endif #endif
...@@ -527,7 +527,7 @@ AtCommit_Notify() ...@@ -527,7 +527,7 @@ AtCommit_Notify()
{ {
rTuple = heap_modifytuple(lTuple, lRel, rTuple = heap_modifytuple(lTuple, lRel,
value, nulls, repl); value, nulls, repl);
heap_replace(lRel, &lTuple->t_self, rTuple); heap_replace(lRel, &lTuple->t_self, rTuple, NULL);
} }
} }
} }
...@@ -741,7 +741,7 @@ ProcessIncomingNotify(void) ...@@ -741,7 +741,7 @@ ProcessIncomingNotify(void)
StartTransactionCommand(); StartTransactionCommand();
lRel = heap_openr(ListenerRelationName); lRel = heap_openr(ListenerRelationName);
RelationSetLockForWrite(lRel); LockRelation(lRel, AccessExclusiveLock);
tdesc = RelationGetDescr(lRel); tdesc = RelationGetDescr(lRel);
/* Scan only entries with my listenerPID */ /* Scan only entries with my listenerPID */
...@@ -772,7 +772,7 @@ ProcessIncomingNotify(void) ...@@ -772,7 +772,7 @@ ProcessIncomingNotify(void)
NotifyMyFrontEnd(relname, sourcePID); NotifyMyFrontEnd(relname, sourcePID);
/* Rewrite the tuple with 0 in notification column */ /* Rewrite the tuple with 0 in notification column */
rTuple = heap_modifytuple(lTuple, lRel, value, nulls, repl); rTuple = heap_modifytuple(lTuple, lRel, value, nulls, repl);
heap_replace(lRel, &lTuple->t_self, rTuple); heap_replace(lRel, &lTuple->t_self, rTuple, NULL);
} }
} }
heap_endscan(sRel); heap_endscan(sRel);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.33 1998/11/27 19:51:54 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.34 1998/12/15 12:45:52 vadim Exp $
* *
* NOTES * NOTES
* The PortalExecutorHeapMemory crap needs to be eliminated * The PortalExecutorHeapMemory crap needs to be eliminated
...@@ -482,7 +482,7 @@ PerformAddAttribute(char *relationName, ...@@ -482,7 +482,7 @@ PerformAddAttribute(char *relationName,
heap_close(attrdesc); heap_close(attrdesc);
((Form_pg_class) GETSTRUCT(reltup))->relnatts = maxatts; ((Form_pg_class) GETSTRUCT(reltup))->relnatts = maxatts;
heap_replace(rel, &reltup->t_self, reltup); heap_replace(rel, &reltup->t_self, reltup, NULL);
/* keep catalog indices current */ /* keep catalog indices current */
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs); CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.64 1998/11/27 19:51:54 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.65 1998/12/15 12:45:53 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -777,6 +777,20 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim) ...@@ -777,6 +777,20 @@ CopyFrom(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
pfree(typmod); pfree(typmod);
} }
pfree(byval); pfree(byval);
/* comments in execUtils.c */
if (has_index)
{
for (i = 0; i < n_indices; i++)
{
if (index_rels[i] == NULL)
continue;
if ((index_rels[i])->rd_rel->relam != BTREE_AM_OID &&
(index_rels[i])->rd_rel->relam != HASH_AM_OID)
UnlockRelation(index_rels[i], AccessExclusiveLock);
index_close(index_rels[i]);
}
}
heap_close(rel); heap_close(rel);
} }
...@@ -914,7 +928,14 @@ GetIndexRelations(Oid main_relation_oid, ...@@ -914,7 +928,14 @@ GetIndexRelations(Oid main_relation_oid,
*index_rels = (Relation *) palloc(*n_indices * sizeof(Relation)); *index_rels = (Relation *) palloc(*n_indices * sizeof(Relation));
for (i = 0, scan = head; i < *n_indices; i++, scan = scan->next) for (i = 0, scan = head; i < *n_indices; i++, scan = scan->next)
{
(*index_rels)[i] = index_open(scan->index_rel_oid); (*index_rels)[i] = index_open(scan->index_rel_oid);
/* comments in execUtils.c */
if ((*index_rels)[i] != NULL &&
((*index_rels)[i])->rd_rel->relam != BTREE_AM_OID &&
((*index_rels)[i])->rd_rel->relam != HASH_AM_OID)
LockRelation((*index_rels)[i], AccessExclusiveLock);
}
for (i = 0, scan = head; i < *n_indices + 1; i++) for (i = 0, scan = head; i < *n_indices + 1; i++)
{ {
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.27 1998/12/14 05:18:43 scrappy Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.28 1998/12/15 12:45:55 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -235,7 +235,7 @@ check_permissions(char *command, ...@@ -235,7 +235,7 @@ check_permissions(char *command,
* delays when multiple 'createdb's or 'destroydb's are run simult. * delays when multiple 'createdb's or 'destroydb's are run simult.
* -mer 7/3/91 * -mer 7/3/91
*/ */
RelationSetLockForWrite(dbrel); LockRelation(dbrel, AccessExclusiveLock);
dbtup = get_pg_dbtup(command, dbname, dbrel); dbtup = get_pg_dbtup(command, dbname, dbrel);
dbfound = HeapTupleIsValid(dbtup); dbfound = HeapTupleIsValid(dbtup);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/defind.c,v 1.28 1998/11/27 19:51:56 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/defind.c,v 1.29 1998/12/15 12:45:56 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -342,7 +342,7 @@ ExtendIndex(char *indexRelationName, Expr *predicate, List *rangetable) ...@@ -342,7 +342,7 @@ ExtendIndex(char *indexRelationName, Expr *predicate, List *rangetable)
heapRelation = heap_open(relationId); heapRelation = heap_open(relationId);
indexRelation = index_open(indexId); indexRelation = index_open(indexId);
RelationSetLockForWrite(heapRelation); LockRelation(heapRelation, ShareLock);
InitIndexStrategy(numberOfAttributes, indexRelation, accessMethodId); InitIndexStrategy(numberOfAttributes, indexRelation, accessMethodId);
......
...@@ -174,7 +174,7 @@ DropProceduralLanguage(DropPLangStmt *stmt) ...@@ -174,7 +174,7 @@ DropProceduralLanguage(DropPLangStmt *stmt)
} }
rel = heap_openr(LanguageRelationName); rel = heap_openr(LanguageRelationName);
heap_delete(rel, &langTup->t_self); heap_delete(rel, &langTup->t_self, NULL);
pfree(langTup); pfree(langTup);
heap_close(rel); heap_close(rel);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.30 1998/11/27 19:51:57 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.31 1998/12/15 12:45:57 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -102,7 +102,7 @@ RemoveOperator(char *operatorName, /* operator name */ ...@@ -102,7 +102,7 @@ RemoveOperator(char *operatorName, /* operator name */
elog(ERROR, "RemoveOperator: operator '%s': permission denied", elog(ERROR, "RemoveOperator: operator '%s': permission denied",
operatorName); operatorName);
#endif #endif
heap_delete(relation, &tup->t_self); heap_delete(relation, &tup->t_self, NULL);
} }
else else
{ {
...@@ -157,7 +157,7 @@ SingleOpOperatorRemove(Oid typeOid) ...@@ -157,7 +157,7 @@ SingleOpOperatorRemove(Oid typeOid)
key[0].sk_attno = attnums[i]; key[0].sk_attno = attnums[i];
scan = heap_beginscan(rel, 0, SnapshotNow, 1, key); scan = heap_beginscan(rel, 0, SnapshotNow, 1, key);
while (HeapTupleIsValid(tup = heap_getnext(scan, 0))) while (HeapTupleIsValid(tup = heap_getnext(scan, 0)))
heap_delete(rel, &tup->t_self); heap_delete(rel, &tup->t_self, NULL);
heap_endscan(scan); heap_endscan(scan);
} }
heap_close(rel); heap_close(rel);
...@@ -268,7 +268,7 @@ RemoveType(char *typeName) /* type name to be removed */ ...@@ -268,7 +268,7 @@ RemoveType(char *typeName) /* type name to be removed */
relation = heap_openr(TypeRelationName); relation = heap_openr(TypeRelationName);
typeOid = tup->t_data->t_oid; typeOid = tup->t_data->t_oid;
heap_delete(relation, &tup->t_self); heap_delete(relation, &tup->t_self, NULL);
/* Now, Delete the "array of" that type */ /* Now, Delete the "array of" that type */
shadow_type = makeArrayTypeName(typeName); shadow_type = makeArrayTypeName(typeName);
...@@ -282,7 +282,7 @@ RemoveType(char *typeName) /* type name to be removed */ ...@@ -282,7 +282,7 @@ RemoveType(char *typeName) /* type name to be removed */
} }
typeOid = tup->t_data->t_oid; typeOid = tup->t_data->t_oid;
heap_delete(relation, &tup->t_self); heap_delete(relation, &tup->t_self, NULL);
heap_close(relation); heap_close(relation);
} }
...@@ -357,7 +357,7 @@ RemoveFunction(char *functionName, /* function name to be removed */ ...@@ -357,7 +357,7 @@ RemoveFunction(char *functionName, /* function name to be removed */
elog(ERROR, "RemoveFunction: function \"%s\" is built-in", functionName); elog(ERROR, "RemoveFunction: function \"%s\" is built-in", functionName);
} }
heap_delete(relation, &tup->t_self); heap_delete(relation, &tup->t_self, NULL);
heap_close(relation); heap_close(relation);
} }
...@@ -428,7 +428,7 @@ RemoveAggregate(char *aggName, char *aggType) ...@@ -428,7 +428,7 @@ RemoveAggregate(char *aggName, char *aggType)
aggName); aggName);
} }
} }
heap_delete(relation, &tup->t_self); heap_delete(relation, &tup->t_self, NULL);
heap_close(relation); heap_close(relation);
} }
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.18 1998/11/27 19:51:57 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.19 1998/12/15 12:45:58 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -180,7 +180,7 @@ renameatt(char *relname, ...@@ -180,7 +180,7 @@ renameatt(char *relname,
newattname, NAMEDATALEN); newattname, NAMEDATALEN);
attrelation = heap_openr(AttributeRelationName); attrelation = heap_openr(AttributeRelationName);
heap_replace(attrelation, &oldatttup->t_self, oldatttup); heap_replace(attrelation, &oldatttup->t_self, oldatttup, NULL);
/* keep system catalog indices current */ /* keep system catalog indices current */
CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, irelations); CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, irelations);
...@@ -248,7 +248,7 @@ renamerel(char *oldrelname, char *newrelname) ...@@ -248,7 +248,7 @@ renamerel(char *oldrelname, char *newrelname)
/* insert fixed rel tuple */ /* insert fixed rel tuple */
relrelation = heap_openr(RelationRelationName); relrelation = heap_openr(RelationRelationName);
heap_replace(relrelation, &oldreltup->t_self, oldreltup); heap_replace(relrelation, &oldreltup->t_self, oldreltup, NULL);
/* keep the system catalog indices current */ /* keep the system catalog indices current */
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, irelations); CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, irelations);
......
...@@ -162,7 +162,7 @@ DefineSequence(CreateSeqStmt *seq) ...@@ -162,7 +162,7 @@ DefineSequence(CreateSeqStmt *seq)
rel = heap_openr(seq->seqname); rel = heap_openr(seq->seqname);
Assert(RelationIsValid(rel)); Assert(RelationIsValid(rel));
RelationSetLockForWrite(rel); LockRelation(rel, AccessExclusiveLock);
tupDesc = RelationGetDescr(rel); tupDesc = RelationGetDescr(rel);
...@@ -185,7 +185,7 @@ DefineSequence(CreateSeqStmt *seq) ...@@ -185,7 +185,7 @@ DefineSequence(CreateSeqStmt *seq)
if (WriteBuffer(buf) == STATUS_ERROR) if (WriteBuffer(buf) == STATUS_ERROR)
elog(ERROR, "DefineSequence: WriteBuffer failed"); elog(ERROR, "DefineSequence: WriteBuffer failed");
RelationUnsetLockForWrite(rel); UnlockRelation(rel, AccessExclusiveLock);
heap_close(rel); heap_close(rel);
return; return;
...@@ -200,7 +200,6 @@ nextval(struct varlena * seqin) ...@@ -200,7 +200,6 @@ nextval(struct varlena * seqin)
SeqTable elm; SeqTable elm;
Buffer buf; Buffer buf;
Form_pg_sequence seq; Form_pg_sequence seq;
ItemPointerData iptr;
int4 incby, int4 incby,
maxv, maxv,
minv, minv,
...@@ -209,7 +208,7 @@ nextval(struct varlena * seqin) ...@@ -209,7 +208,7 @@ nextval(struct varlena * seqin)
next, next,
rescnt = 0; rescnt = 0;
/* open and WIntentLock sequence */ /* open and AccessShareLock sequence */
elm = init_sequence("nextval", seqname); elm = init_sequence("nextval", seqname);
pfree(seqname); pfree(seqname);
...@@ -219,7 +218,7 @@ nextval(struct varlena * seqin) ...@@ -219,7 +218,7 @@ nextval(struct varlena * seqin)
return elm->last; return elm->last;
} }
seq = read_info("nextval", elm, &buf); /* lock page and read seq = read_info("nextval", elm, &buf); /* lock page' buffer and read
* tuple */ * tuple */
next = result = seq->last_value; next = result = seq->last_value;
...@@ -282,12 +281,11 @@ nextval(struct varlena * seqin) ...@@ -282,12 +281,11 @@ nextval(struct varlena * seqin)
seq->last_value = next; /* last fetched number */ seq->last_value = next; /* last fetched number */
seq->is_called = 't'; seq->is_called = 't';
LockBuffer(buf, BUFFER_LOCK_UNLOCK);
if (WriteBuffer(buf) == STATUS_ERROR) if (WriteBuffer(buf) == STATUS_ERROR)
elog(ERROR, "%s.nextval: WriteBuffer failed", elm->name); elog(ERROR, "%s.nextval: WriteBuffer failed", elm->name);
ItemPointerSet(&iptr, 0, FirstOffsetNumber);
RelationUnsetSingleWLockPage(elm->rel, &iptr);
return result; return result;
} }
...@@ -300,7 +298,7 @@ currval(struct varlena * seqin) ...@@ -300,7 +298,7 @@ currval(struct varlena * seqin)
SeqTable elm; SeqTable elm;
int4 result; int4 result;
/* open and WIntentLock sequence */ /* open and AccessShareLock sequence */
elm = init_sequence("currval", seqname); elm = init_sequence("currval", seqname);
pfree(seqname); pfree(seqname);
...@@ -320,7 +318,6 @@ setval(struct varlena * seqin, int4 next) ...@@ -320,7 +318,6 @@ setval(struct varlena * seqin, int4 next)
SeqTable elm; SeqTable elm;
Buffer buf; Buffer buf;
Form_pg_sequence seq; Form_pg_sequence seq;
ItemPointerData iptr;
#ifndef NO_SECURITY #ifndef NO_SECURITY
if (pg_aclcheck(seqname, getpgusername(), ACL_WR) != ACLCHECK_OK) if (pg_aclcheck(seqname, getpgusername(), ACL_WR) != ACLCHECK_OK)
...@@ -328,9 +325,9 @@ setval(struct varlena * seqin, int4 next) ...@@ -328,9 +325,9 @@ setval(struct varlena * seqin, int4 next)
seqname, seqname); seqname, seqname);
#endif #endif
/* open and WIntentLock sequence */ /* open and AccessShareLock sequence */
elm = init_sequence("setval", seqname); elm = init_sequence("setval", seqname);
seq = read_info("setval", elm, &buf); /* lock page and read seq = read_info("setval", elm, &buf); /* lock page' buffer and read
* tuple */ * tuple */
if (seq->cache_value != 1) if (seq->cache_value != 1)
...@@ -353,27 +350,22 @@ setval(struct varlena * seqin, int4 next) ...@@ -353,27 +350,22 @@ setval(struct varlena * seqin, int4 next)
seq->last_value = next; /* last fetched number */ seq->last_value = next; /* last fetched number */
seq->is_called = 't'; seq->is_called = 't';
LockBuffer(buf, BUFFER_LOCK_UNLOCK);
if (WriteBuffer(buf) == STATUS_ERROR) if (WriteBuffer(buf) == STATUS_ERROR)
elog(ERROR, "%s.settval: WriteBuffer failed", seqname); elog(ERROR, "%s.settval: WriteBuffer failed", seqname);
ItemPointerSet(&iptr, 0, FirstOffsetNumber);
RelationUnsetSingleWLockPage(elm->rel, &iptr);
return next; return next;
} }
static Form_pg_sequence static Form_pg_sequence
read_info(char *caller, SeqTable elm, Buffer *buf) read_info(char *caller, SeqTable elm, Buffer *buf)
{ {
ItemPointerData iptr; PageHeader page;
PageHeader page; ItemId lp;
ItemId lp;
HeapTupleData tuple; HeapTupleData tuple;
sequence_magic *sm; sequence_magic *sm;
Form_pg_sequence seq; Form_pg_sequence seq;
ItemPointerSet(&iptr, 0, FirstOffsetNumber);
RelationSetSingleWLockPage(elm->rel, &iptr);
if (RelationGetNumberOfBlocks(elm->rel) != 1) if (RelationGetNumberOfBlocks(elm->rel) != 1)
elog(ERROR, "%s.%s: invalid number of blocks in sequence", elog(ERROR, "%s.%s: invalid number of blocks in sequence",
...@@ -383,6 +375,8 @@ read_info(char *caller, SeqTable elm, Buffer *buf) ...@@ -383,6 +375,8 @@ read_info(char *caller, SeqTable elm, Buffer *buf)
if (!BufferIsValid(*buf)) if (!BufferIsValid(*buf))
elog(ERROR, "%s.%s: ReadBuffer failed", elm->name, caller); elog(ERROR, "%s.%s: ReadBuffer failed", elm->name, caller);
LockBuffer(*buf, BUFFER_LOCK_EXCLUSIVE);
page = (PageHeader) BufferGetPage(*buf); page = (PageHeader) BufferGetPage(*buf);
sm = (sequence_magic *) PageGetSpecialPointer(page); sm = (sequence_magic *) PageGetSpecialPointer(page);
...@@ -439,7 +433,7 @@ init_sequence(char *caller, char *name) ...@@ -439,7 +433,7 @@ init_sequence(char *caller, char *name)
if (!RelationIsValid(temp->rel)) if (!RelationIsValid(temp->rel))
elog(ERROR, "%s.%s: sequence does not exist", name, caller); elog(ERROR, "%s.%s: sequence does not exist", name, caller);
RelationSetWIntentLock(temp->rel); LockRelation(temp->rel, AccessShareLock);
if (temp->rel->rd_rel->relkind != RELKIND_SEQUENCE) if (temp->rel->rd_rel->relkind != RELKIND_SEQUENCE)
elog(ERROR, "%s.%s: %s is not sequence !", name, caller, name); elog(ERROR, "%s.%s: %s is not sequence !", name, caller, name);
...@@ -485,7 +479,7 @@ CloseSequences(void) ...@@ -485,7 +479,7 @@ CloseSequences(void)
{ {
rel = elm->rel; rel = elm->rel;
elm->rel = (Relation) NULL; elm->rel = (Relation) NULL;
RelationUnsetWIntentLock(rel); UnlockRelation(rel, AccessShareLock);
heap_close(rel); heap_close(rel);
} }
elm = elm->next; elm = elm->next;
......
This diff is collapsed.
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: user.c,v 1.22 1998/12/14 08:11:00 scrappy Exp $ * $Id: user.c,v 1.23 1998/12/15 12:46:00 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -136,7 +136,7 @@ DefineUser(CreateUserStmt *stmt) ...@@ -136,7 +136,7 @@ DefineUser(CreateUserStmt *stmt)
* Secure a write lock on pg_shadow so we can be sure of what the next * Secure a write lock on pg_shadow so we can be sure of what the next
* usesysid should be. * usesysid should be.
*/ */
RelationSetLockForWrite(pg_shadow_rel); LockRelation(pg_shadow_rel, AccessExclusiveLock);
scan = heap_beginscan(pg_shadow_rel, false, SnapshotNow, 0, NULL); scan = heap_beginscan(pg_shadow_rel, false, SnapshotNow, 0, NULL);
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0))) while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
...@@ -154,7 +154,7 @@ DefineUser(CreateUserStmt *stmt) ...@@ -154,7 +154,7 @@ DefineUser(CreateUserStmt *stmt)
if (exists) if (exists)
{ {
RelationUnsetLockForWrite(pg_shadow_rel); UnlockRelation(pg_shadow_rel, AccessExclusiveLock);
heap_close(pg_shadow_rel); heap_close(pg_shadow_rel);
UserAbortTransactionBlock(); UserAbortTransactionBlock();
elog(ERROR, elog(ERROR,
...@@ -187,7 +187,7 @@ DefineUser(CreateUserStmt *stmt) ...@@ -187,7 +187,7 @@ DefineUser(CreateUserStmt *stmt)
* This goes after the UpdatePgPwdFile to be certain that two backends * This goes after the UpdatePgPwdFile to be certain that two backends
* to not attempt to write to the pg_pwd file at the same time. * to not attempt to write to the pg_pwd file at the same time.
*/ */
RelationUnsetLockForWrite(pg_shadow_rel); UnlockRelation(pg_shadow_rel, AccessExclusiveLock);
heap_close(pg_shadow_rel); heap_close(pg_shadow_rel);
if (IsTransactionBlock() && !inblock) if (IsTransactionBlock() && !inblock)
...@@ -235,14 +235,14 @@ AlterUser(AlterUserStmt *stmt) ...@@ -235,14 +235,14 @@ AlterUser(AlterUserStmt *stmt)
* dump of the pg_pwd file is done, there is not another backend doing * dump of the pg_pwd file is done, there is not another backend doing
* the same. * the same.
*/ */
RelationSetLockForWrite(pg_shadow_rel); LockRelation(pg_shadow_rel, AccessExclusiveLock);
tuple = SearchSysCacheTuple(USENAME, tuple = SearchSysCacheTuple(USENAME,
PointerGetDatum(stmt->user), PointerGetDatum(stmt->user),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
{ {
RelationUnsetLockForWrite(pg_shadow_rel); UnlockRelation(pg_shadow_rel, AccessExclusiveLock);
heap_close(pg_shadow_rel); heap_close(pg_shadow_rel);
UserAbortTransactionBlock(); /* needed? */ UserAbortTransactionBlock(); /* needed? */
elog(ERROR, "alterUser: user \"%s\" does not exist", stmt->user); elog(ERROR, "alterUser: user \"%s\" does not exist", stmt->user);
...@@ -288,7 +288,7 @@ AlterUser(AlterUserStmt *stmt) ...@@ -288,7 +288,7 @@ AlterUser(AlterUserStmt *stmt)
UpdatePgPwdFile(sql); UpdatePgPwdFile(sql);
RelationUnsetLockForWrite(pg_shadow_rel); UnlockRelation(pg_shadow_rel, AccessExclusiveLock);
heap_close(pg_shadow_rel); heap_close(pg_shadow_rel);
if (IsTransactionBlock() && !inblock) if (IsTransactionBlock() && !inblock)
...@@ -342,14 +342,14 @@ RemoveUser(char *user) ...@@ -342,14 +342,14 @@ RemoveUser(char *user)
* dump of the pg_pwd file is done, there is not another backend doing * dump of the pg_pwd file is done, there is not another backend doing
* the same. * the same.
*/ */
RelationSetLockForWrite(pg_shadow_rel); LockRelation(pg_shadow_rel, AccessExclusiveLock);
tuple = SearchSysCacheTuple(USENAME, tuple = SearchSysCacheTuple(USENAME,
PointerGetDatum(user), PointerGetDatum(user),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
{ {
RelationUnsetLockForWrite(pg_shadow_rel); UnlockRelation(pg_shadow_rel, AccessExclusiveLock);
heap_close(pg_shadow_rel); heap_close(pg_shadow_rel);
UserAbortTransactionBlock(); UserAbortTransactionBlock();
elog(ERROR, "removeUser: user \"%s\" does not exist", user); elog(ERROR, "removeUser: user \"%s\" does not exist", user);
...@@ -422,7 +422,7 @@ RemoveUser(char *user) ...@@ -422,7 +422,7 @@ RemoveUser(char *user)
UpdatePgPwdFile(sql); UpdatePgPwdFile(sql);
RelationUnsetLockForWrite(pg_shadow_rel); UnlockRelation(pg_shadow_rel, AccessExclusiveLock);
heap_close(pg_shadow_rel); heap_close(pg_shadow_rel);
if (IsTransactionBlock() && !inblock) if (IsTransactionBlock() && !inblock)
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.91 1998/11/27 19:51:58 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.92 1998/12/15 12:46:01 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -497,7 +497,7 @@ vc_vacone(Oid relid, bool analyze, List *va_cols) ...@@ -497,7 +497,7 @@ vc_vacone(Oid relid, bool analyze, List *va_cols)
} }
/* we require the relation to be locked until the indices are cleaned */ /* we require the relation to be locked until the indices are cleaned */
RelationSetLockForWrite(onerel); LockRelation(onerel, AccessExclusiveLock);
/* scan it */ /* scan it */
vacuum_pages.vpl_num_pages = fraged_pages.vpl_num_pages = 0; vacuum_pages.vpl_num_pages = fraged_pages.vpl_num_pages = 0;
...@@ -1918,7 +1918,7 @@ vc_delhilowstats(Oid relid, int attcnt, int *attnums) ...@@ -1918,7 +1918,7 @@ vc_delhilowstats(Oid relid, int attcnt, int *attnums)
if (i >= attcnt) if (i >= attcnt)
continue; /* don't delete it */ continue; /* don't delete it */
} }
heap_delete(pgstatistic, &tuple->t_self); heap_delete(pgstatistic, &tuple->t_self, NULL);
} }
heap_endscan(scan); heap_endscan(scan);
...@@ -1928,11 +1928,7 @@ vc_delhilowstats(Oid relid, int attcnt, int *attnums) ...@@ -1928,11 +1928,7 @@ vc_delhilowstats(Oid relid, int attcnt, int *attnums)
static void static void
vc_setpagelock(Relation rel, BlockNumber blkno) vc_setpagelock(Relation rel, BlockNumber blkno)
{ {
ItemPointerData itm; LockPage(rel, blkno, ExclusiveLock);
ItemPointerSet(&itm, blkno, 1);
RelationSetLockForWritePage(rel, &itm);
} }
/* /*
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.59 1998/11/27 19:51:59 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.60 1998/12/15 12:46:04 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
/* #include "access/localam.h" */ /* #include "access/localam.h" */
#include "optimizer/var.h" #include "optimizer/var.h"
#include "access/heapam.h" #include "access/heapam.h"
#include "access/xact.h"
#include "catalog/heap.h" #include "catalog/heap.h"
#include "commands/trigger.h" #include "commands/trigger.h"
...@@ -421,7 +422,6 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate) ...@@ -421,7 +422,6 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
{ {
/****************** /******************
* if we have a result relation, open it and * if we have a result relation, open it and
* initialize the result relation info stuff. * initialize the result relation info stuff.
****************** ******************
*/ */
...@@ -440,14 +440,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate) ...@@ -440,14 +440,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
elog(ERROR, "You can't change sequence relation %s", elog(ERROR, "You can't change sequence relation %s",
resultRelationDesc->rd_rel->relname.data); resultRelationDesc->rd_rel->relname.data);
/* LockRelation(resultRelationDesc, RowExclusiveLock);
* Write-lock the result relation right away: if the relation is
* used in a subsequent scan, we won't have to elevate the
* read-lock set by heap_beginscan to a write-lock (needed by
* heap_insert, heap_delete and heap_replace). This will hopefully
* prevent some deadlocks. - 01/24/94
*/
RelationSetLockForWrite(resultRelationDesc);
resultRelationInfo = makeNode(RelationInfo); resultRelationInfo = makeNode(RelationInfo);
resultRelationInfo->ri_RangeTableIndex = resultRelationIndex; resultRelationInfo->ri_RangeTableIndex = resultRelationIndex;
...@@ -461,7 +454,8 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate) ...@@ -461,7 +454,8 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
* in the result relation information.. * in the result relation information..
****************** ******************
*/ */
ExecOpenIndices(resultRelationOid, resultRelationInfo); if (operation != CMD_DELETE)
ExecOpenIndices(resultRelationOid, resultRelationInfo);
estate->es_result_relation_info = resultRelationInfo; estate->es_result_relation_info = resultRelationInfo;
} }
...@@ -1006,8 +1000,10 @@ ExecDelete(TupleTableSlot *slot, ...@@ -1006,8 +1000,10 @@ ExecDelete(TupleTableSlot *slot,
ItemPointer tupleid, ItemPointer tupleid,
EState *estate) EState *estate)
{ {
RelationInfo *resultRelationInfo; RelationInfo *resultRelationInfo;
Relation resultRelationDesc; Relation resultRelationDesc;
ItemPointerData ctid;
int result;
/****************** /******************
* get the result relation information * get the result relation information
...@@ -1022,19 +1018,35 @@ ExecDelete(TupleTableSlot *slot, ...@@ -1022,19 +1018,35 @@ ExecDelete(TupleTableSlot *slot,
{ {
bool dodelete; bool dodelete;
dodelete = ExecBRDeleteTriggers(resultRelationDesc, tupleid); dodelete = ExecBRDeleteTriggers(estate, tupleid);
if (!dodelete) /* "do nothing" */ if (!dodelete) /* "do nothing" */
return; return;
} }
/****************** /*
* delete the tuple * delete the tuple
******************
*/ */
if (heap_delete(resultRelationDesc, /* relation desc */ result = heap_delete(resultRelationDesc, tupleid, &ctid);
tupleid)) /* item pointer to tuple */ switch (result)
return; {
case HeapTupleSelfUpdated:
return;
case HeapTupleMayBeUpdated:
break;
case HeapTupleUpdated:
if (XactIsoLevel == XACT_SERIALIZED)
elog(ERROR, "Serialize access failed due to concurrent update");
else
elog(ERROR, "Isolation level %u is not supported", XactIsoLevel);
return;
default:
elog(ERROR, "Unknown status %u from heap_delete", result);
return;
}
IncrDeleted(); IncrDeleted();
(estate->es_processed)++; (estate->es_processed)++;
...@@ -1054,7 +1066,7 @@ ExecDelete(TupleTableSlot *slot, ...@@ -1054,7 +1066,7 @@ ExecDelete(TupleTableSlot *slot,
/* AFTER ROW DELETE Triggers */ /* AFTER ROW DELETE Triggers */
if (resultRelationDesc->trigdesc && if (resultRelationDesc->trigdesc &&
resultRelationDesc->trigdesc->n_after_row[TRIGGER_EVENT_DELETE] > 0) resultRelationDesc->trigdesc->n_after_row[TRIGGER_EVENT_DELETE] > 0)
ExecARDeleteTriggers(resultRelationDesc, tupleid); ExecARDeleteTriggers(estate, tupleid);
} }
...@@ -1075,10 +1087,12 @@ ExecReplace(TupleTableSlot *slot, ...@@ -1075,10 +1087,12 @@ ExecReplace(TupleTableSlot *slot,
EState *estate, EState *estate,
Query *parseTree) Query *parseTree)
{ {
HeapTuple tuple; HeapTuple tuple;
RelationInfo *resultRelationInfo; RelationInfo *resultRelationInfo;
Relation resultRelationDesc; Relation resultRelationDesc;
int numIndices; ItemPointerData ctid;
int result;
int numIndices;
/****************** /******************
* abort the operation if not running transactions * abort the operation if not running transactions
...@@ -1117,7 +1131,7 @@ ExecReplace(TupleTableSlot *slot, ...@@ -1117,7 +1131,7 @@ ExecReplace(TupleTableSlot *slot,
{ {
HeapTuple newtuple; HeapTuple newtuple;
newtuple = ExecBRUpdateTriggers(resultRelationDesc, tupleid, tuple); newtuple = ExecBRUpdateTriggers(estate, tupleid, tuple);
if (newtuple == NULL) /* "do nothing" */ if (newtuple == NULL) /* "do nothing" */
return; return;
...@@ -1140,19 +1154,28 @@ ExecReplace(TupleTableSlot *slot, ...@@ -1140,19 +1154,28 @@ ExecReplace(TupleTableSlot *slot,
ExecConstraints("ExecReplace", resultRelationDesc, tuple); ExecConstraints("ExecReplace", resultRelationDesc, tuple);
} }
/****************** /*
* replace the heap tuple * replace the heap tuple
*
* Don't want to continue if our heap_replace didn't actually
* do a replace. This would be the case if heap_replace
* detected a non-functional update. -kw 12/30/93
******************
*/ */
if (heap_replace(resultRelationDesc, /* relation desc */ result = heap_replace(resultRelationDesc, tupleid, tuple, &ctid);
tupleid, /* item ptr of tuple to replace */ switch (result)
tuple)) {
{ /* replacement heap tuple */ case HeapTupleSelfUpdated:
return; return;
case HeapTupleMayBeUpdated:
break;
case HeapTupleUpdated:
if (XactIsoLevel == XACT_SERIALIZED)
elog(ERROR, "Serialize access failed due to concurrent update");
else
elog(ERROR, "Isolation level %u is not supported", XactIsoLevel);
return;
default:
elog(ERROR, "Unknown status %u from heap_replace", result);
return;
} }
IncrReplaced(); IncrReplaced();
...@@ -1187,7 +1210,7 @@ ExecReplace(TupleTableSlot *slot, ...@@ -1187,7 +1210,7 @@ ExecReplace(TupleTableSlot *slot,
/* AFTER ROW UPDATE Triggers */ /* AFTER ROW UPDATE Triggers */
if (resultRelationDesc->trigdesc && if (resultRelationDesc->trigdesc &&
resultRelationDesc->trigdesc->n_after_row[TRIGGER_EVENT_UPDATE] > 0) resultRelationDesc->trigdesc->n_after_row[TRIGGER_EVENT_UPDATE] > 0)
ExecARUpdateTriggers(resultRelationDesc, tupleid, tuple); ExecARUpdateTriggers(estate, tupleid, tuple);
} }
#if 0 #if 0
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.40 1998/11/27 19:52:01 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.41 1998/12/15 12:46:05 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -868,7 +868,23 @@ ExecOpenIndices(Oid resultRelationOid, ...@@ -868,7 +868,23 @@ ExecOpenIndices(Oid resultRelationOid,
indexOid = lfirsti(indexoid); indexOid = lfirsti(indexoid);
indexDesc = index_open(indexOid); indexDesc = index_open(indexOid);
if (indexDesc != NULL) if (indexDesc != NULL)
{
relationDescs[i++] = indexDesc; relationDescs[i++] = indexDesc;
/*
* Hack for not btree and hash indices: they use relation level
* exclusive locking on updation (i.e. - they are not ready
* for MVCC) and so we have to exclusively lock indices here
* to prevent deadlocks if we will scan them - index_beginscan
* places AccessShareLock, indices update methods don't use
* locks at all. We release this lock in ExecCloseIndices.
* Note, that hashes use page level locking - i.e. are not
* deadlock-free, - let's them be on their way -:))
* vadim 03-12-1998
*/
if (indexDesc->rd_rel->relam != BTREE_AM_OID &&
indexDesc->rd_rel->relam != HASH_AM_OID)
LockRelation(indexDesc, AccessExclusiveLock);
}
} }
/* ---------------- /* ----------------
...@@ -948,9 +964,18 @@ ExecCloseIndices(RelationInfo *resultRelationInfo) ...@@ -948,9 +964,18 @@ ExecCloseIndices(RelationInfo *resultRelationInfo)
relationDescs = resultRelationInfo->ri_IndexRelationDescs; relationDescs = resultRelationInfo->ri_IndexRelationDescs;
for (i = 0; i < numIndices; i++) for (i = 0; i < numIndices; i++)
if (relationDescs[i] != NULL) {
index_close(relationDescs[i]); if (relationDescs[i] == NULL)
continue;
/*
* Notes in ExecOpenIndices.
*/
if (relationDescs[i]->rd_rel->relam != BTREE_AM_OID &&
relationDescs[i]->rd_rel->relam != HASH_AM_OID)
UnlockRelation(relationDescs[i], AccessExclusiveLock);
index_close(relationDescs[i]);
}
/* /*
* XXX should free indexInfo array here too. * XXX should free indexInfo array here too.
*/ */
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* *
* $Id: nodeHash.c,v 1.27 1998/12/14 08:11:02 scrappy Exp $ * $Id: nodeHash.c,v 1.28 1998/12/15 12:46:06 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -693,13 +693,13 @@ ExecScanHashBucket(HashJoinState *hjstate, ...@@ -693,13 +693,13 @@ ExecScanHashBucket(HashJoinState *hjstate,
else else
heapTuple = (HeapTuple) heapTuple = (HeapTuple)
LONGALIGN(((char *) curtuple + curtuple->t_len + HEAPTUPLESIZE)); LONGALIGN(((char *) curtuple + curtuple->t_len + HEAPTUPLESIZE));
heapTuple->t_data = (HeapTupleHeader)
((char *) heapTuple + HEAPTUPLESIZE);
while (heapTuple < (HeapTuple) ABSADDR(bucket->bottom)) while (heapTuple < (HeapTuple) ABSADDR(bucket->bottom))
{ {
heapTuple->t_data = (HeapTupleHeader)
((char *) heapTuple + HEAPTUPLESIZE);
inntuple = ExecStoreTuple(heapTuple, /* tuple to store */ inntuple = ExecStoreTuple(heapTuple, /* tuple to store */
hjstate->hj_HashTupleSlot, /* slot */ hjstate->hj_HashTupleSlot, /* slot */
InvalidBuffer, /* tuple has no buffer */ InvalidBuffer, /* tuple has no buffer */
...@@ -713,8 +713,6 @@ ExecScanHashBucket(HashJoinState *hjstate, ...@@ -713,8 +713,6 @@ ExecScanHashBucket(HashJoinState *hjstate,
heapTuple = (HeapTuple) heapTuple = (HeapTuple)
LONGALIGN(((char *) heapTuple + heapTuple->t_len + HEAPTUPLESIZE)); LONGALIGN(((char *) heapTuple + heapTuple->t_len + HEAPTUPLESIZE));
heapTuple->t_data = (HeapTupleHeader)
((char *) heapTuple + HEAPTUPLESIZE);
} }
if (firstotuple == NULL) if (firstotuple == NULL)
......
...@@ -235,7 +235,7 @@ ...@@ -235,7 +235,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/Attic/gram.c,v 2.51 1998/12/14 05:18:57 scrappy Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/Attic/gram.c,v 2.52 1998/12/15 12:46:08 vadim Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.34 1998/12/13 23:54:40 thomas Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.35 1998/12/15 12:46:14 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1115,7 +1115,6 @@ find_inheritors(Oid relid, Oid **supervec) ...@@ -1115,7 +1115,6 @@ find_inheritors(Oid relid, Oid **supervec)
inhrel = heap_openr(InheritsRelationName); inhrel = heap_openr(InheritsRelationName);
RelationSetLockForRead(inhrel);
inhtupdesc = RelationGetDescr(inhrel); inhtupdesc = RelationGetDescr(inhrel);
/* /*
...@@ -1182,7 +1181,6 @@ find_inheritors(Oid relid, Oid **supervec) ...@@ -1182,7 +1181,6 @@ find_inheritors(Oid relid, Oid **supervec)
} }
} while (qentry != (SuperQE *) NULL); } while (qentry != (SuperQE *) NULL);
RelationUnsetLockForRead(inhrel);
heap_close(inhrel); heap_close(inhrel);
if (nvisited > 0) if (nvisited > 0)
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.20 1998/12/14 00:02:17 thomas Exp $ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.21 1998/12/15 12:46:16 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -127,7 +127,7 @@ RemoveRewriteRule(char *ruleName) ...@@ -127,7 +127,7 @@ RemoveRewriteRule(char *ruleName)
/* /*
* Now delete the tuple... * Now delete the tuple...
*/ */
heap_delete(RewriteRelation, &tuple->t_self); heap_delete(RewriteRelation, &tuple->t_self, NULL);
pfree(tuple); pfree(tuple);
heap_close(RewriteRelation); heap_close(RewriteRelation);
...@@ -164,7 +164,7 @@ RelationRemoveRules(Oid relid) ...@@ -164,7 +164,7 @@ RelationRemoveRules(Oid relid)
0, SnapshotNow, 1, &scanKeyData); 0, SnapshotNow, 1, &scanKeyData);
while (HeapTupleIsValid(tuple = heap_getnext(scanDesc, 0))) while (HeapTupleIsValid(tuple = heap_getnext(scanDesc, 0)))
heap_delete(RewriteRelation, &tuple->t_self); heap_delete(RewriteRelation, &tuple->t_self, NULL);
heap_endscan(scanDesc); heap_endscan(scanDesc);
heap_close(RewriteRelation); heap_close(RewriteRelation);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteSupport.c,v 1.29 1998/11/27 19:52:18 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteSupport.c,v 1.30 1998/12/15 12:46:18 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -128,7 +128,7 @@ setRelhasrulesInRelation(Oid relationId, bool relhasrules) ...@@ -128,7 +128,7 @@ setRelhasrulesInRelation(Oid relationId, bool relhasrules)
relationRelation = heap_openr(RelationRelationName); relationRelation = heap_openr(RelationRelationName);
((Form_pg_class) GETSTRUCT(tuple))->relhasrules = relhasrules; ((Form_pg_class) GETSTRUCT(tuple))->relhasrules = relhasrules;
heap_replace(relationRelation, &tuple->t_self, tuple); heap_replace(relationRelation, &tuple->t_self, tuple, NULL);
/* keep the catalog indices up to date */ /* keep the catalog indices up to date */
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs); CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_init.c,v 1.19 1998/09/01 04:31:39 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_init.c,v 1.20 1998/12/15 12:46:18 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -62,13 +62,13 @@ BufferBlock BufferBlocks; ...@@ -62,13 +62,13 @@ BufferBlock BufferBlocks;
#ifndef HAS_TEST_AND_SET #ifndef HAS_TEST_AND_SET
long *NWaitIOBackendP; long *NWaitIOBackendP;
#endif #endif
extern IpcSemaphoreId WaitIOSemId; extern IpcSemaphoreId WaitIOSemId;
long *PrivateRefCount; /* also used in freelist.c */ long *PrivateRefCount; /* also used in freelist.c */
long *LastRefCount; /* refcounts of last ExecMain level */ long *LastRefCount; /* refcounts of last ExecMain level */
bits8 *BufferLocks; /* */
long *CommitInfoNeedsSave;/* to write buffers where we have filled long *CommitInfoNeedsSave;/* to write buffers where we have filled
* in t_infomask */ * in t_infomask */
...@@ -146,21 +146,6 @@ InitBufferPool(IPCKey key) ...@@ -146,21 +146,6 @@ InitBufferPool(IPCKey key)
foundDescs; foundDescs;
int i; int i;
/* check padding of BufferDesc and BufferHdr */
/*
* we need both checks because a sbufdesc_padded >
* PADDED_SBUFDESC_SIZE will shrink sbufdesc to the required size,
* which is bad
*/
if (sizeof(struct sbufdesc) != PADDED_SBUFDESC_SIZE ||
sizeof(struct sbufdesc_unpadded) > PADDED_SBUFDESC_SIZE)
elog(ERROR, "Internal error: sbufdesc does not have the proper size, "
"contact the Postgres developers");
if (sizeof(struct sbufdesc_unpadded) <= PADDED_SBUFDESC_SIZE / 2)
elog(ERROR, "Internal error: sbufdesc is greatly over-sized, "
"contact the Postgres developers");
Data_Descriptors = NBuffers; Data_Descriptors = NBuffers;
Free_List_Descriptor = Data_Descriptors; Free_List_Descriptor = Data_Descriptors;
Lookup_List_Descriptor = Data_Descriptors + 1; Lookup_List_Descriptor = Data_Descriptors + 1;
...@@ -232,6 +217,7 @@ InitBufferPool(IPCKey key) ...@@ -232,6 +217,7 @@ InitBufferPool(IPCKey key)
buf->buf_id = i; buf->buf_id = i;
#ifdef HAS_TEST_AND_SET #ifdef HAS_TEST_AND_SET
S_INIT_LOCK(&(buf->io_in_progress_lock)); S_INIT_LOCK(&(buf->io_in_progress_lock));
S_INIT_LOCK(&(buf->cntx_lock));
#endif #endif
} }
...@@ -252,10 +238,15 @@ InitBufferPool(IPCKey key) ...@@ -252,10 +238,15 @@ InitBufferPool(IPCKey key)
WaitIOSemId = IpcSemaphoreCreate(IPCKeyGetWaitIOSemaphoreKey(key), WaitIOSemId = IpcSemaphoreCreate(IPCKeyGetWaitIOSemaphoreKey(key),
1, IPCProtection, 0, 1, &status); 1, IPCProtection, 0, 1, &status);
WaitCLSemId = IpcSemaphoreCreate(IPCKeyGetWaitCLSemaphoreKey(key),
1, IPCProtection,
IpcSemaphoreDefaultStartValue,
1, &status);
} }
#endif #endif
PrivateRefCount = (long *) calloc(NBuffers, sizeof(long)); PrivateRefCount = (long *) calloc(NBuffers, sizeof(long));
LastRefCount = (long *) calloc(NBuffers, sizeof(long)); LastRefCount = (long *) calloc(NBuffers, sizeof(long));
BufferLocks = (bits8*) calloc (NBuffers, sizeof(bits8));
CommitInfoNeedsSave = (long *) calloc(NBuffers, sizeof(long)); CommitInfoNeedsSave = (long *) calloc(NBuffers, sizeof(long));
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.44 1998/10/08 18:29:54 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.45 1998/12/15 12:46:19 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -86,7 +86,6 @@ static void WaitIO(BufferDesc *buf, SPINLOCK spinlock); ...@@ -86,7 +86,6 @@ static void WaitIO(BufferDesc *buf, SPINLOCK spinlock);
#ifndef HAS_TEST_AND_SET #ifndef HAS_TEST_AND_SET
static void SignalIO(BufferDesc *buf); static void SignalIO(BufferDesc *buf);
extern long *NWaitIOBackendP; /* defined in buf_init.c */ extern long *NWaitIOBackendP; /* defined in buf_init.c */
#endif /* HAS_TEST_AND_SET */ #endif /* HAS_TEST_AND_SET */
static Buffer ReadBufferWithBufferLock(Relation relation, BlockNumber blockNum, static Buffer ReadBufferWithBufferLock(Relation relation, BlockNumber blockNum,
...@@ -583,7 +582,6 @@ BufferAlloc(Relation reln, ...@@ -583,7 +582,6 @@ BufferAlloc(Relation reln,
if (buf->refcount > 1) if (buf->refcount > 1)
SignalIO(buf); SignalIO(buf);
#endif /* !HAS_TEST_AND_SET */ #endif /* !HAS_TEST_AND_SET */
/* give up the buffer since we don't need it any more */ /* give up the buffer since we don't need it any more */
buf->refcount--; buf->refcount--;
PrivateRefCount[BufferDescriptorGetBuffer(buf) - 1] = 0; PrivateRefCount[BufferDescriptorGetBuffer(buf) - 1] = 0;
...@@ -1096,6 +1094,7 @@ WaitIO(BufferDesc *buf, SPINLOCK spinlock) ...@@ -1096,6 +1094,7 @@ WaitIO(BufferDesc *buf, SPINLOCK spinlock)
#else /* HAS_TEST_AND_SET */ #else /* HAS_TEST_AND_SET */
IpcSemaphoreId WaitIOSemId; IpcSemaphoreId WaitIOSemId;
IpcSemaphoreId WaitCLSemId;
static void static void
WaitIO(BufferDesc *buf, SPINLOCK spinlock) WaitIO(BufferDesc *buf, SPINLOCK spinlock)
...@@ -1933,3 +1932,147 @@ SetBufferCommitInfoNeedsSave(Buffer buffer) ...@@ -1933,3 +1932,147 @@ SetBufferCommitInfoNeedsSave(Buffer buffer)
if (!BufferIsLocal(buffer)) if (!BufferIsLocal(buffer))
CommitInfoNeedsSave[buffer - 1]++; CommitInfoNeedsSave[buffer - 1]++;
} }
void
UnlockBuffers()
{
BufferDesc *buf;
int i;
for (i = 0; i < NBuffers; i++)
{
if (BufferLocks[i] == 0)
continue;
Assert(BufferIsValid(i+1));
buf = &(BufferDescriptors[i]);
#ifdef HAS_TEST_AND_SET
S_LOCK(&(buf->cntx_lock));
#else
IpcSemaphoreLock(WaitCLSemId, 0, IpcExclusiveLock);
#endif
if (BufferLocks[i] & BL_R_LOCK)
{
Assert(buf->r_locks > 0);
(buf->r_locks)--;
}
if (BufferLocks[i] & BL_RI_LOCK)
{
Assert(buf->ri_lock);
buf->ri_lock = false;
}
if (BufferLocks[i] & BL_W_LOCK)
{
Assert(buf->w_lock);
buf->w_lock = false;
}
#ifdef HAS_TEST_AND_SET
S_UNLOCK(&(buf->cntx_lock));
#else
IpcSemaphoreUnlock(WaitCLSemId, 0, IpcExclusiveLock);
#endif
BufferLocks[i] = 0;
}
}
void
LockBuffer (Buffer buffer, int mode)
{
BufferDesc *buf;
Assert(BufferIsValid(buffer));
if (BufferIsLocal(buffer))
return;
buf = &(BufferDescriptors[buffer-1]);
#ifdef HAS_TEST_AND_SET
S_LOCK(&(buf->cntx_lock));
#else
IpcSemaphoreLock(WaitCLSemId, 0, IpcExclusiveLock);
#endif
if (mode == BUFFER_LOCK_UNLOCK)
{
if (BufferLocks[buffer-1] & BL_R_LOCK)
{
Assert(buf->r_locks > 0);
Assert(!(buf->w_lock));
Assert(!(BufferLocks[buffer-1] & (BL_W_LOCK | BL_RI_LOCK)))
(buf->r_locks)--;
BufferLocks[buffer-1] &= ~BL_R_LOCK;
}
else if (BufferLocks[buffer-1] & BL_W_LOCK)
{
Assert(buf->w_lock);
Assert(buf->r_locks == 0 && !buf->ri_lock);
Assert(!(BufferLocks[buffer-1] & (BL_R_LOCK | BL_RI_LOCK)))
buf->w_lock = false;
BufferLocks[buffer-1] &= ~BL_W_LOCK;
}
else
elog(ERROR, "UNLockBuffer: buffer %u is not locked", buffer);
}
else if (mode == BUFFER_LOCK_SHARE)
{
unsigned i = 0;
Assert(!(BufferLocks[buffer-1] & (BL_R_LOCK | BL_W_LOCK | BL_RI_LOCK)));
while (buf->ri_lock || buf->w_lock)
{
#ifdef HAS_TEST_AND_SET
S_UNLOCK(&(buf->cntx_lock));
s_lock_sleep(i++);
S_LOCK(&(buf->cntx_lock));
#else
IpcSemaphoreUnlock(WaitCLSemId, 0, IpcExclusiveLock);
s_lock_sleep(i++)
IpcSemaphoreLock(WaitCLSemId, 0, IpcExclusiveLock);
#endif
}
(buf->r_locks)++;
BufferLocks[buffer-1] |= BL_R_LOCK;
}
else if (mode == BUFFER_LOCK_EXCLUSIVE)
{
unsigned i = 0;
Assert(!(BufferLocks[buffer-1] & (BL_R_LOCK | BL_W_LOCK | BL_RI_LOCK)));
while (buf->r_locks > 0 || buf->w_lock)
{
if (buf->r_locks > 3)
{
if (!(BufferLocks[buffer-1] & BL_RI_LOCK))
BufferLocks[buffer-1] |= BL_RI_LOCK;
buf->ri_lock = true;
}
#ifdef HAS_TEST_AND_SET
S_UNLOCK(&(buf->cntx_lock));
s_lock_sleep(i++);
S_LOCK(&(buf->cntx_lock));
#else
IpcSemaphoreUnlock(WaitCLSemId, 0, IpcExclusiveLock);
s_lock_sleep(i++)
IpcSemaphoreLock(WaitCLSemId, 0, IpcExclusiveLock);
#endif
}
buf->w_lock = true;
BufferLocks[buffer-1] |= BL_W_LOCK;
if (BufferLocks[buffer-1] & BL_RI_LOCK)
{
buf->ri_lock = false;
BufferLocks[buffer-1] &= ~BL_RI_LOCK;
}
}
else
elog(ERROR, "LockBuffer: unknown lock mode %d", mode);
#ifdef HAS_TEST_AND_SET
S_UNLOCK(&(buf->cntx_lock));
#else
IpcSemaphoreUnlock(WaitCLSemId, 0, IpcExclusiveLock);
#endif
}
...@@ -7,13 +7,14 @@ ...@@ -7,13 +7,14 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/Attic/s_lock.c,v 1.12 1998/09/18 17:18:39 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/Attic/s_lock.c,v 1.13 1998/12/15 12:46:21 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include <stdio.h> #include <stdio.h>
#include <sys/time.h> #include <sys/time.h>
#include <unistd.h>
#include "config.h" #include "config.h"
#include "c.h" #include "c.h"
...@@ -52,6 +53,16 @@ s_lock_stuck(volatile slock_t *lock, const char *file, const int line) ...@@ -52,6 +53,16 @@ s_lock_stuck(volatile slock_t *lock, const char *file, const int line)
} }
void
s_lock_sleep(unsigned spin)
{
struct timeval delay;
delay.tv_sec = 0;
delay.tv_usec = s_spincycle[spin % S_NSPINCYCLE];
(void) select(0, NULL, NULL, NULL, &delay);
}
/* /*
* s_lock(lock) - take a spinlock with backoff * s_lock(lock) - take a spinlock with backoff
...@@ -59,15 +70,11 @@ s_lock_stuck(volatile slock_t *lock, const char *file, const int line) ...@@ -59,15 +70,11 @@ s_lock_stuck(volatile slock_t *lock, const char *file, const int line)
void void
s_lock(volatile slock_t *lock, const char *file, const int line) s_lock(volatile slock_t *lock, const char *file, const int line)
{ {
int spins = 0; unsigned spins = 0;
while (TAS(lock)) while (TAS(lock))
{ {
struct timeval delay; s_lock_sleep(spins);
delay.tv_sec = 0;
delay.tv_usec = s_spincycle[spins % S_NSPINCYCLE];
(void) select(0, NULL, NULL, NULL, &delay);
if (++spins > S_MAX_BUSY) if (++spins > S_MAX_BUSY)
{ {
/* It's been over a minute... */ /* It's been over a minute... */
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipci.c,v 1.16 1998/09/01 03:25:10 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipci.c,v 1.17 1998/12/15 12:46:24 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "postgres.h" #include "postgres.h"
#include "storage/ipc.h" #include "storage/ipc.h"
#include "storage/multilev.h"
#include "storage/sinval.h" #include "storage/sinval.h"
#include "storage/bufmgr.h" #include "storage/bufmgr.h"
#include "storage/proc.h" #include "storage/proc.h"
...@@ -92,7 +91,7 @@ CreateSharedMemoryAndSemaphores(IPCKey key) ...@@ -92,7 +91,7 @@ CreateSharedMemoryAndSemaphores(IPCKey key)
* ---------------- * ----------------
*/ */
InitLocks(); InitLocks();
if (InitMultiLevelLocks() == INVALID_TABLEID) if (InitLockTable() == INVALID_TABLEID)
elog(FATAL, "Couldn't create the lock table"); elog(FATAL, "Couldn't create the lock table");
/* ---------------- /* ----------------
...@@ -145,7 +144,7 @@ AttachSharedMemoryAndSemaphores(IPCKey key) ...@@ -145,7 +144,7 @@ AttachSharedMemoryAndSemaphores(IPCKey key)
* ---------------- * ----------------
*/ */
InitLocks(); InitLocks();
if (InitMultiLevelLocks() == INVALID_TABLEID) if (InitLockTable() == INVALID_TABLEID)
elog(FATAL, "Couldn't attach to the lock table"); elog(FATAL, "Couldn't attach to the lock table");
AttachSharedInvalidationState(key); AttachSharedInvalidationState(key);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmem.c,v 1.31 1998/09/01 04:31:49 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/storage/ipc/shmem.c,v 1.32 1998/12/15 12:46:24 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -68,7 +68,8 @@ ...@@ -68,7 +68,8 @@
#include "utils/dynahash.h" #include "utils/dynahash.h"
#include "utils/hsearch.h" #include "utils/hsearch.h"
#include "utils/memutils.h" #include "utils/memutils.h"
#include "access/transam.h" #include "access/xact.h"
#include "utils/tqual.h"
/* shared memory global variables */ /* shared memory global variables */
...@@ -629,7 +630,6 @@ TransactionIdIsInProgress(TransactionId xid) ...@@ -629,7 +630,6 @@ TransactionIdIsInProgress(TransactionId xid)
return false; return false;
} }
#ifdef LowLevelLocking
/* /*
* GetSnapshotData -- returns information about running transactions. * GetSnapshotData -- returns information about running transactions.
* *
...@@ -645,16 +645,15 @@ Snapshot ...@@ -645,16 +645,15 @@ Snapshot
GetSnapshotData(bool serialized) GetSnapshotData(bool serialized)
{ {
Snapshot snapshot = (Snapshot) malloc(sizeof(SnapshotData)); Snapshot snapshot = (Snapshot) malloc(sizeof(SnapshotData));
TransactionId snapshot->xip = (TransactionId *)
malloc(32 * sizeof(TransactionId));
ShmemIndexEnt *result; ShmemIndexEnt *result;
PROC *proc; PROC *proc;
TransactionId cid = GetCurrentTransactionId(); TransactionId cid = GetCurrentTransactionId();
uint count = 0; uint32 count = 0;
unit free = 31; uint32 have = 31;
Assert(ShmemIndex); Assert(ShmemIndex);
snapshot->xip = (TransactionId *) malloc(32 * sizeof(TransactionId));
snapshot->xmax = cid; snapshot->xmax = cid;
snapshot->xmin = cid; snapshot->xmin = cid;
...@@ -676,20 +675,20 @@ GetSnapshotData(bool serialized) ...@@ -676,20 +675,20 @@ GetSnapshotData(bool serialized)
continue; continue;
proc = (PROC *) MAKE_PTR(result->location); proc = (PROC *) MAKE_PTR(result->location);
if (proc == MyProc || proc->xid < FirstTransactionId || if (proc == MyProc || proc->xid < FirstTransactionId ||
serialized && proc->xid >= cid) (serialized && proc->xid >= cid))
continue; continue;
if (proc->xid < snapshot->xmin) if (proc->xid < snapshot->xmin)
snapshot->xmin = proc->xid; snapshot->xmin = proc->xid;
else if (proc->xid > snapshot->xmax) else if (proc->xid > snapshot->xmax)
snapshot->xmax = proc->xid; snapshot->xmax = proc->xid;
if (free == 0) if (have == 0)
{ {
snapshot->xip = (TransactionId *) realloc(snapshot->xip, snapshot->xip = (TransactionId *) realloc(snapshot->xip,
(count + 33) * sizeof(TransactionId)); (count + 33) * sizeof(TransactionId));
free = 32; have = 32;
} }
snapshot->xip[count] = proc->xid; snapshot->xip[count] = proc->xid;
free--; have--;
count++; count++;
} }
...@@ -699,5 +698,3 @@ GetSnapshotData(bool serialized) ...@@ -699,5 +698,3 @@ GetSnapshotData(bool serialized)
elog(ERROR, "GetSnapshotData: ShmemIndex corrupted"); elog(ERROR, "GetSnapshotData: ShmemIndex corrupted");
return NULL; return NULL;
} }
#endif
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.43 1998/12/13 05:07:50 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.44 1998/12/15 12:46:26 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -203,12 +203,12 @@ inv_create(int flags) ...@@ -203,12 +203,12 @@ inv_create(int flags)
if (flags & INV_WRITE) if (flags & INV_WRITE)
{ {
RelationSetLockForWrite(r); LockRelation(r, ExclusiveLock);
retval->flags = IFS_WRLOCK | IFS_RDLOCK; retval->flags = IFS_WRLOCK | IFS_RDLOCK;
} }
else if (flags & INV_READ) else if (flags & INV_READ)
{ {
RelationSetLockForRead(r); LockRelation(r, ShareLock);
retval->flags = IFS_RDLOCK; retval->flags = IFS_RDLOCK;
} }
retval->flags |= IFS_ATEOF; retval->flags |= IFS_ATEOF;
...@@ -254,12 +254,12 @@ inv_open(Oid lobjId, int flags) ...@@ -254,12 +254,12 @@ inv_open(Oid lobjId, int flags)
if (flags & INV_WRITE) if (flags & INV_WRITE)
{ {
RelationSetLockForWrite(r); LockRelation(r, ExclusiveLock);
retval->flags = IFS_WRLOCK | IFS_RDLOCK; retval->flags = IFS_WRLOCK | IFS_RDLOCK;
} }
else if (flags & INV_READ) else if (flags & INV_READ)
{ {
RelationSetLockForRead(r); LockRelation(r, ShareLock);
retval->flags = IFS_RDLOCK; retval->flags = IFS_RDLOCK;
} }
...@@ -328,7 +328,7 @@ inv_stat(LargeObjectDesc *obj_desc, struct pgstat * stbuf) ...@@ -328,7 +328,7 @@ inv_stat(LargeObjectDesc *obj_desc, struct pgstat * stbuf)
/* need read lock for stat */ /* need read lock for stat */
if (!(obj_desc->flags & IFS_RDLOCK)) if (!(obj_desc->flags & IFS_RDLOCK))
{ {
RelationSetLockForRead(obj_desc->heap_r); LockRelation(obj_desc->heap_r, ShareLock);
obj_desc->flags |= IFS_RDLOCK; obj_desc->flags |= IFS_RDLOCK;
} }
...@@ -376,7 +376,7 @@ inv_seek(LargeObjectDesc *obj_desc, int offset, int whence) ...@@ -376,7 +376,7 @@ inv_seek(LargeObjectDesc *obj_desc, int offset, int whence)
/* need read lock for getsize */ /* need read lock for getsize */
if (!(obj_desc->flags & IFS_RDLOCK)) if (!(obj_desc->flags & IFS_RDLOCK))
{ {
RelationSetLockForRead(obj_desc->heap_r); LockRelation(obj_desc->heap_r, ShareLock);
obj_desc->flags |= IFS_RDLOCK; obj_desc->flags |= IFS_RDLOCK;
} }
offset += _inv_getsize(obj_desc->heap_r, offset += _inv_getsize(obj_desc->heap_r,
...@@ -458,7 +458,7 @@ inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes) ...@@ -458,7 +458,7 @@ inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
/* make sure we obey two-phase locking */ /* make sure we obey two-phase locking */
if (!(obj_desc->flags & IFS_RDLOCK)) if (!(obj_desc->flags & IFS_RDLOCK))
{ {
RelationSetLockForRead(obj_desc->heap_r); LockRelation(obj_desc->heap_r, ShareLock);
obj_desc->flags |= IFS_RDLOCK; obj_desc->flags |= IFS_RDLOCK;
} }
...@@ -516,7 +516,7 @@ inv_write(LargeObjectDesc *obj_desc, char *buf, int nbytes) ...@@ -516,7 +516,7 @@ inv_write(LargeObjectDesc *obj_desc, char *buf, int nbytes)
if (!(obj_desc->flags & IFS_WRLOCK)) if (!(obj_desc->flags & IFS_WRLOCK))
{ {
RelationSetLockForRead(obj_desc->heap_r); LockRelation(obj_desc->heap_r, ShareLock);
obj_desc->flags |= (IFS_WRLOCK | IFS_RDLOCK); obj_desc->flags |= (IFS_WRLOCK | IFS_RDLOCK);
} }
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# Makefile for storage/lmgr # Makefile for storage/lmgr
# #
# IDENTIFICATION # IDENTIFICATION
# $Header: /cvsroot/pgsql/src/backend/storage/lmgr/Makefile,v 1.8 1998/07/26 04:30:40 scrappy Exp $ # $Header: /cvsroot/pgsql/src/backend/storage/lmgr/Makefile,v 1.9 1998/12/15 12:46:29 vadim Exp $
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
...@@ -16,7 +16,7 @@ ifdef MULTIBYTE ...@@ -16,7 +16,7 @@ ifdef MULTIBYTE
CFLAGS+= $(MBFLAGS) CFLAGS+= $(MBFLAGS)
endif endif
OBJS = lmgr.o lock.o multi.o proc.o single.o OBJS = lmgr.o lock.o proc.o
all: SUBSYS.o all: SUBSYS.o
......
This diff is collapsed.
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.38 1998/10/08 18:29:57 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.39 1998/12/15 12:46:30 vadim Exp $
* *
* NOTES * NOTES
* Outside modules can create a lock table and acquire/release * Outside modules can create a lock table and acquire/release
...@@ -84,7 +84,7 @@ static int WaitOnLock(LOCKMETHOD lockmethod, LOCK *lock, LOCKMODE lockmode, ...@@ -84,7 +84,7 @@ static int WaitOnLock(LOCKMETHOD lockmethod, LOCK *lock, LOCKMODE lockmode,
#define LOCK_PRINT_AUX(where,lock,type) \ #define LOCK_PRINT_AUX(where,lock,type) \
TPRINTF(TRACE_ALL, \ TPRINTF(TRACE_ALL, \
"%s: lock(%x) tbl(%d) rel(%d) db(%d) tid(%d,%d) mask(%x) " \ "%s: lock(%x) tbl(%d) rel(%d) db(%d) obj(%u) mask(%x) " \
"hold(%d,%d,%d,%d,%d)=%d " \ "hold(%d,%d,%d,%d,%d)=%d " \
"act(%d,%d,%d,%d,%d)=%d wait(%d) type(%s)", \ "act(%d,%d,%d,%d,%d)=%d wait(%d) type(%s)", \
where, \ where, \
...@@ -92,9 +92,7 @@ static int WaitOnLock(LOCKMETHOD lockmethod, LOCK *lock, LOCKMODE lockmode, ...@@ -92,9 +92,7 @@ static int WaitOnLock(LOCKMETHOD lockmethod, LOCK *lock, LOCKMODE lockmode,
lock->tag.lockmethod, \ lock->tag.lockmethod, \
lock->tag.relId, \ lock->tag.relId, \
lock->tag.dbId, \ lock->tag.dbId, \
((lock->tag.tupleId.ip_blkid.bi_hi<<16)+ \ lock->tag.objId.blkno, \
lock->tag.tupleId.ip_blkid.bi_lo), \
lock->tag.tupleId.ip_posid, \
lock->mask, \ lock->mask, \
lock->holders[1], \ lock->holders[1], \
lock->holders[2], \ lock->holders[2], \
...@@ -498,10 +496,8 @@ LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag, LOCKMODE lockmode) ...@@ -498,10 +496,8 @@ LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag, LOCKMODE lockmode)
if (is_user_lock) if (is_user_lock)
{ {
#ifdef USER_LOCKS_DEBUG #ifdef USER_LOCKS_DEBUG
TPRINTF(TRACE_USERLOCKS, "LockAcquire: user lock [%u,%u] %s", TPRINTF(TRACE_USERLOCKS, "LockAcquire: user lock [%u] %s",
locktag->tupleId.ip_posid, locktag->objId.blkno,
((locktag->tupleId.ip_blkid.bi_hi << 16) +
locktag->tupleId.ip_blkid.bi_lo),
lock_types[lockmode]); lock_types[lockmode]);
#endif #endif
} }
...@@ -550,8 +546,7 @@ LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag, LOCKMODE lockmode) ...@@ -550,8 +546,7 @@ LockAcquire(LOCKMETHOD lockmethod, LOCKTAG *locktag, LOCKMODE lockmode)
MemSet((char *) lock->holders, 0, sizeof(int) * MAX_LOCKMODES); MemSet((char *) lock->holders, 0, sizeof(int) * MAX_LOCKMODES);
MemSet((char *) lock->activeHolders, 0, sizeof(int) * MAX_LOCKMODES); MemSet((char *) lock->activeHolders, 0, sizeof(int) * MAX_LOCKMODES);
ProcQueueInit(&(lock->waitProcs)); ProcQueueInit(&(lock->waitProcs));
Assert(BlockIdEquals(&(lock->tag.tupleId.ip_blkid), Assert(lock->tag.objId.blkno == locktag->objId.blkno);
&(locktag->tupleId.ip_blkid)));
LOCK_PRINT("LockAcquire: new", lock, lockmode); LOCK_PRINT("LockAcquire: new", lock, lockmode);
} }
else else
...@@ -993,10 +988,8 @@ LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag, LOCKMODE lockmode) ...@@ -993,10 +988,8 @@ LockRelease(LOCKMETHOD lockmethod, LOCKTAG *locktag, LOCKMODE lockmode)
is_user_lock = (lockmethod == USER_LOCKMETHOD); is_user_lock = (lockmethod == USER_LOCKMETHOD);
if (is_user_lock) if (is_user_lock)
{ {
TPRINTF(TRACE_USERLOCKS, "LockRelease: user lock tag [%u,%u] %d", TPRINTF(TRACE_USERLOCKS, "LockRelease: user lock tag [%u] %d",
locktag->tupleId.ip_posid, locktag->objId.blkno,
((locktag->tupleId.ip_blkid.bi_hi << 16) +
locktag->tupleId.ip_blkid.bi_lo),
lockmode); lockmode);
} }
#endif #endif
...@@ -1336,19 +1329,15 @@ LockReleaseAll(LOCKMETHOD lockmethod, SHM_QUEUE *lockQueue) ...@@ -1336,19 +1329,15 @@ LockReleaseAll(LOCKMETHOD lockmethod, SHM_QUEUE *lockQueue)
{ {
/* Should never happen */ /* Should never happen */
elog(NOTICE, elog(NOTICE,
"LockReleaseAll: INVALID PID: [%u,%u] [%d,%d,%d]", "LockReleaseAll: INVALID PID: [%u] [%d,%d,%d]",
lock->tag.tupleId.ip_posid, lock->tag.objId.blkno,
((lock->tag.tupleId.ip_blkid.bi_hi << 16) +
lock->tag.tupleId.ip_blkid.bi_lo),
xidLook->tag.lock, xidLook->tag.pid, xidLook->tag.xid); xidLook->tag.lock, xidLook->tag.pid, xidLook->tag.xid);
nleft++; nleft++;
goto next_item; goto next_item;
} }
TPRINTF(TRACE_USERLOCKS, TPRINTF(TRACE_USERLOCKS,
"LockReleaseAll: releasing user lock [%u,%u] [%d,%d,%d]", "LockReleaseAll: releasing user lock [%u] [%d,%d,%d]",
lock->tag.tupleId.ip_posid, lock->tag.objId.blkno,
((lock->tag.tupleId.ip_blkid.bi_hi << 16) +
lock->tag.tupleId.ip_blkid.bi_lo),
xidLook->tag.lock, xidLook->tag.pid, xidLook->tag.xid); xidLook->tag.lock, xidLook->tag.pid, xidLook->tag.xid);
} }
else else
...@@ -1361,10 +1350,8 @@ LockReleaseAll(LOCKMETHOD lockmethod, SHM_QUEUE *lockQueue) ...@@ -1361,10 +1350,8 @@ LockReleaseAll(LOCKMETHOD lockmethod, SHM_QUEUE *lockQueue)
if (xidLook->tag.pid != 0) if (xidLook->tag.pid != 0)
{ {
TPRINTF(TRACE_LOCKS, TPRINTF(TRACE_LOCKS,
"LockReleaseAll: skiping user lock [%u,%u] [%d,%d,%d]", "LockReleaseAll: skiping user lock [%u] [%d,%d,%d]",
lock->tag.tupleId.ip_posid, lock->tag.objId.blkno,
((lock->tag.tupleId.ip_blkid.bi_hi << 16) +
lock->tag.tupleId.ip_blkid.bi_lo),
xidLook->tag.lock, xidLook->tag.pid, xidLook->tag.xid); xidLook->tag.lock, xidLook->tag.pid, xidLook->tag.xid);
nleft++; nleft++;
goto next_item; goto next_item;
...@@ -1649,7 +1636,7 @@ DeadLockCheck(SHM_QUEUE *lockQueue, LOCK *findlock, bool skip_check) ...@@ -1649,7 +1636,7 @@ DeadLockCheck(SHM_QUEUE *lockQueue, LOCK *findlock, bool skip_check)
*/ */
Assert(skip_check); Assert(skip_check);
Assert(MyProc->prio == 2); Assert(MyProc->prio >= 2);
lockMethodTable = LockMethodTable[1]; lockMethodTable = LockMethodTable[1];
xidTable = lockMethodTable->xidHash; xidTable = lockMethodTable->xidHash;
...@@ -1747,10 +1734,8 @@ LockOwners(LOCKMETHOD lockmethod, LOCKTAG *locktag) ...@@ -1747,10 +1734,8 @@ LockOwners(LOCKMETHOD lockmethod, LOCKTAG *locktag)
is_user_lock = (lockmethod == USER_LOCKMETHOD); is_user_lock = (lockmethod == USER_LOCKMETHOD);
if (is_user_lock) if (is_user_lock)
{ {
TPRINTF(TRACE_USERLOCKS, "LockOwners: user lock tag [%u,%u]", TPRINTF(TRACE_USERLOCKS, "LockOwners: user lock tag [%u]",
locktag->tupleId.ip_posid, locktag->objId.blkno;,
((locktag->tupleId.ip_blkid.bi_hi << 16) +
locktag->tupleId.ip_blkid.bi_lo));
} }
#endif #endif
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.19 1998/11/27 19:52:23 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.20 1998/12/15 12:46:34 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -109,7 +109,7 @@ SetDefine(char *querystr, char *typename) ...@@ -109,7 +109,7 @@ SetDefine(char *querystr, char *typename)
/* change the pg_proc tuple */ /* change the pg_proc tuple */
procrel = heap_openr(ProcedureRelationName); procrel = heap_openr(ProcedureRelationName);
RelationSetLockForWrite(procrel); LockRelation(procrel, AccessExclusiveLock);
tup = SearchSysCacheTuple(PROOID, tup = SearchSysCacheTuple(PROOID,
ObjectIdGetDatum(setoid), ObjectIdGetDatum(setoid),
...@@ -123,7 +123,7 @@ SetDefine(char *querystr, char *typename) ...@@ -123,7 +123,7 @@ SetDefine(char *querystr, char *typename)
repl); repl);
setheapoverride(true); setheapoverride(true);
heap_replace(procrel, &tup->t_self, newtup); heap_replace(procrel, &tup->t_self, newtup, NULL);
setheapoverride(false); setheapoverride(false);
setoid = newtup->t_data->t_oid; setoid = newtup->t_data->t_oid;
...@@ -139,7 +139,7 @@ SetDefine(char *querystr, char *typename) ...@@ -139,7 +139,7 @@ SetDefine(char *querystr, char *typename)
CatalogIndexInsert(idescs, Num_pg_proc_indices, procrel, newtup); CatalogIndexInsert(idescs, Num_pg_proc_indices, procrel, newtup);
CatalogCloseIndices(Num_pg_proc_indices, idescs); CatalogCloseIndices(Num_pg_proc_indices, idescs);
} }
RelationUnsetLockForWrite(procrel); UnlockRelation(procrel, AccessExclusiveLock);
heap_close(procrel); heap_close(procrel);
} }
return setoid; return setoid;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.51 1998/11/27 19:52:28 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.52 1998/12/15 12:46:37 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -363,8 +363,6 @@ scan_pg_rel_seq(RelationBuildDescInfo buildinfo) ...@@ -363,8 +363,6 @@ scan_pg_rel_seq(RelationBuildDescInfo buildinfo)
* ---------------- * ----------------
*/ */
pg_class_desc = heap_openr(RelationRelationName); pg_class_desc = heap_openr(RelationRelationName);
if (!IsInitProcessingMode())
RelationSetLockForRead(pg_class_desc);
pg_class_scan = heap_beginscan(pg_class_desc, 0, SnapshotNow, 1, &key); pg_class_scan = heap_beginscan(pg_class_desc, 0, SnapshotNow, 1, &key);
pg_class_tuple = heap_getnext(pg_class_scan, 0); pg_class_tuple = heap_getnext(pg_class_scan, 0);
...@@ -388,8 +386,6 @@ scan_pg_rel_seq(RelationBuildDescInfo buildinfo) ...@@ -388,8 +386,6 @@ scan_pg_rel_seq(RelationBuildDescInfo buildinfo)
/* all done */ /* all done */
heap_endscan(pg_class_scan); heap_endscan(pg_class_scan);
if (!IsInitProcessingMode())
RelationUnsetLockForRead(pg_class_desc);
heap_close(pg_class_desc); heap_close(pg_class_desc);
return return_tuple; return return_tuple;
...@@ -403,7 +399,7 @@ scan_pg_rel_ind(RelationBuildDescInfo buildinfo) ...@@ -403,7 +399,7 @@ scan_pg_rel_ind(RelationBuildDescInfo buildinfo)
pg_class_desc = heap_openr(RelationRelationName); pg_class_desc = heap_openr(RelationRelationName);
if (!IsInitProcessingMode()) if (!IsInitProcessingMode())
RelationSetLockForRead(pg_class_desc); LockRelation(pg_class_desc, AccessShareLock);
switch (buildinfo.infotype) switch (buildinfo.infotype)
{ {
...@@ -428,7 +424,7 @@ scan_pg_rel_ind(RelationBuildDescInfo buildinfo) ...@@ -428,7 +424,7 @@ scan_pg_rel_ind(RelationBuildDescInfo buildinfo)
/* all done */ /* all done */
if (!IsInitProcessingMode()) if (!IsInitProcessingMode())
RelationUnsetLockForRead(pg_class_desc); UnlockRelation(pg_class_desc, AccessShareLock);
heap_close(pg_class_desc); heap_close(pg_class_desc);
return return_tuple; return return_tuple;
...@@ -1126,7 +1122,6 @@ RelationIdCacheGetRelation(Oid relationId) ...@@ -1126,7 +1122,6 @@ RelationIdCacheGetRelation(Oid relationId)
} }
RelationIncrementReferenceCount(rd); RelationIncrementReferenceCount(rd);
RelationSetLockForDescriptorOpen(rd);
} }
...@@ -1159,7 +1154,6 @@ RelationNameCacheGetRelation(char *relationName) ...@@ -1159,7 +1154,6 @@ RelationNameCacheGetRelation(char *relationName)
} }
RelationIncrementReferenceCount(rd); RelationIncrementReferenceCount(rd);
RelationSetLockForDescriptorOpen(rd);
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.20 1998/11/27 19:52:36 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.21 1998/12/15 12:46:40 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -26,6 +26,9 @@ ...@@ -26,6 +26,9 @@
extern bool PostgresIsInitialized; extern bool PostgresIsInitialized;
SnapshotData SnapshotDirtyData;
Snapshot SnapshotDirty = &SnapshotDirtyData;
/* /*
* XXX Transaction system override hacks start here * XXX Transaction system override hacks start here
*/ */
...@@ -88,8 +91,9 @@ HeapTupleSatisfiesItself(HeapTupleHeader tuple) ...@@ -88,8 +91,9 @@ HeapTupleSatisfiesItself(HeapTupleHeader tuple)
{ {
if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */ if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
return true; return true;
else if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
return false; return true;
return false;
} }
if (!TransactionIdDidCommit(tuple->t_xmin)) if (!TransactionIdDidCommit(tuple->t_xmin))
...@@ -107,10 +111,18 @@ HeapTupleSatisfiesItself(HeapTupleHeader tuple) ...@@ -107,10 +111,18 @@ HeapTupleSatisfiesItself(HeapTupleHeader tuple)
return true; return true;
if (tuple->t_infomask & HEAP_XMAX_COMMITTED) if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
return false; {
if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
return true;
return false; /* updated by other */
}
if (TransactionIdIsCurrentTransactionId(tuple->t_xmax)) if (TransactionIdIsCurrentTransactionId(tuple->t_xmax))
{
if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
return true;
return false; return false;
}
if (!TransactionIdDidCommit(tuple->t_xmax)) if (!TransactionIdDidCommit(tuple->t_xmax))
{ {
...@@ -122,6 +134,9 @@ HeapTupleSatisfiesItself(HeapTupleHeader tuple) ...@@ -122,6 +134,9 @@ HeapTupleSatisfiesItself(HeapTupleHeader tuple)
/* by here, deleting transaction has committed */ /* by here, deleting transaction has committed */
tuple->t_infomask |= HEAP_XMAX_COMMITTED; tuple->t_infomask |= HEAP_XMAX_COMMITTED;
if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
return true;
return false; return false;
} }
...@@ -152,13 +167,6 @@ HeapTupleSatisfiesItself(HeapTupleHeader tuple) ...@@ -152,13 +167,6 @@ HeapTupleSatisfiesItself(HeapTupleHeader tuple)
* (Xmax is not committed && the row was deleted by another transaction * (Xmax is not committed && the row was deleted by another transaction
* Xmax != my-transaction)))) that has not been committed * Xmax != my-transaction)))) that has not been committed
* *
* XXX
* CommandId stuff didn't work properly if one used SQL-functions in
* UPDATE/INSERT(fromSELECT)/DELETE scans: SQL-funcs call
* CommandCounterIncrement and made tuples changed/inserted by
* current command visible to command itself (so we had multiple
* update of updated tuples, etc). - vadim 08/29/97
*
* mao says 17 march 1993: the tests in this routine are correct; * mao says 17 march 1993: the tests in this routine are correct;
* if you think they're not, you're wrong, and you should think * if you think they're not, you're wrong, and you should think
* about it again. i know, it happened to me. we don't need to * about it again. i know, it happened to me. we don't need to
...@@ -203,6 +211,9 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple) ...@@ -203,6 +211,9 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple)
Assert(TransactionIdIsCurrentTransactionId(tuple->t_xmax)); Assert(TransactionIdIsCurrentTransactionId(tuple->t_xmax));
if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
return true;
if (CommandIdGEScanCommandId(tuple->t_cmax)) if (CommandIdGEScanCommandId(tuple->t_cmax))
return true; /* deleted after scan started */ return true; /* deleted after scan started */
else else
...@@ -229,10 +240,16 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple) ...@@ -229,10 +240,16 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple)
return true; return true;
if (tuple->t_infomask & HEAP_XMAX_COMMITTED) if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
{
if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
return true;
return false; return false;
}
if (TransactionIdIsCurrentTransactionId(tuple->t_xmax)) if (TransactionIdIsCurrentTransactionId(tuple->t_xmax))
{ {
if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
return true;
if (CommandIdGEScanCommandId(tuple->t_cmax)) if (CommandIdGEScanCommandId(tuple->t_cmax))
return true; /* deleted after scan started */ return true; /* deleted after scan started */
else else
...@@ -249,5 +266,173 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple) ...@@ -249,5 +266,173 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple)
/* xmax transaction committed */ /* xmax transaction committed */
tuple->t_infomask |= HEAP_XMAX_COMMITTED; tuple->t_infomask |= HEAP_XMAX_COMMITTED;
if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
return true;
return false; return false;
} }
int
HeapTupleSatisfiesUpdate(HeapTuple tuple)
{
HeapTupleHeader th = tuple->t_data;
if (AMI_OVERRIDE)
return HeapTupleMayBeUpdated;
if (!(th->t_infomask & HEAP_XMIN_COMMITTED))
{
if (th->t_infomask & HEAP_XMIN_INVALID) /* xid invalid or aborted */
return HeapTupleInvisible;
if (TransactionIdIsCurrentTransactionId(th->t_xmin))
{
if (CommandIdGEScanCommandId(th->t_cmin) && !heapisoverride())
return HeapTupleInvisible; /* inserted after scan started */
if (th->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
return HeapTupleMayBeUpdated;
Assert(TransactionIdIsCurrentTransactionId(th->t_xmax));
if (th->t_infomask & HEAP_MARKED_FOR_UPDATE)
return HeapTupleMayBeUpdated;
if (CommandIdGEScanCommandId(th->t_cmax))
return HeapTupleSelfUpdated;/* updated after scan started */
else
return HeapTupleInvisible; /* updated before scan started */
}
/*
* This call is VERY expensive - requires a log table lookup.
* Actually, this should be done by query before...
*/
if (!TransactionIdDidCommit(th->t_xmin))
{
if (TransactionIdDidAbort(th->t_xmin))
th->t_infomask |= HEAP_XMIN_INVALID; /* aborted */
return HeapTupleInvisible;
}
th->t_infomask |= HEAP_XMIN_COMMITTED;
}
/* by here, the inserting transaction has committed */
if (th->t_infomask & HEAP_XMAX_INVALID) /* xid invalid or aborted */
return HeapTupleMayBeUpdated;
if (th->t_infomask & HEAP_XMAX_COMMITTED)
{
if (th->t_infomask & HEAP_MARKED_FOR_UPDATE)
return HeapTupleMayBeUpdated;
return HeapTupleUpdated; /* updated by other */
}
if (TransactionIdIsCurrentTransactionId(th->t_xmax))
{
if (th->t_infomask & HEAP_MARKED_FOR_UPDATE)
return HeapTupleMayBeUpdated;
if (CommandIdGEScanCommandId(th->t_cmax))
return HeapTupleSelfUpdated;/* updated after scan started */
else
return HeapTupleInvisible; /* updated before scan started */
}
if (!TransactionIdDidCommit(th->t_xmax))
{
if (TransactionIdDidAbort(th->t_xmax))
{
th->t_infomask |= HEAP_XMAX_INVALID; /* aborted */
return HeapTupleMayBeUpdated;
}
/* running xact */
return HeapTupleBeingUpdated; /* in updation by other */
}
/* xmax transaction committed */
th->t_infomask |= HEAP_XMAX_COMMITTED;
if (th->t_infomask & HEAP_MARKED_FOR_UPDATE)
return HeapTupleMayBeUpdated;
return HeapTupleUpdated; /* updated by other */
}
bool
HeapTupleSatisfiesDirty(HeapTupleHeader tuple)
{
SnapshotDirty->xmin = SnapshotDirty->xmax = InvalidTransactionId;
if (AMI_OVERRIDE)
return true;
if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
{
if (tuple->t_infomask & HEAP_XMIN_INVALID) /* xid invalid or aborted */
return false;
if (TransactionIdIsCurrentTransactionId(tuple->t_xmin))
{
if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */
return true;
Assert(TransactionIdIsCurrentTransactionId(tuple->t_xmax));
if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
return true;
return false;
}
if (!TransactionIdDidCommit(tuple->t_xmin))
{
if (TransactionIdDidAbort(tuple->t_xmin))
{
tuple->t_infomask |= HEAP_XMIN_INVALID; /* aborted */
return false;
}
SnapshotDirty->xmin = tuple->t_xmin;
return true; /* in insertion by other */
}
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
}
/* by here, the inserting transaction has committed */
if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid or aborted */
return true;
if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
{
if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
return true;
return false; /* updated by other */
}
if (TransactionIdIsCurrentTransactionId(tuple->t_xmax))
return false;
if (!TransactionIdDidCommit(tuple->t_xmax))
{
if (TransactionIdDidAbort(tuple->t_xmax))
{
tuple->t_infomask |= HEAP_XMAX_INVALID; /* aborted */
return true;
}
/* running xact */
SnapshotDirty->xmax = tuple->t_xmax;
return true; /* in updation by other */
}
/* xmax transaction committed */
tuple->t_infomask |= HEAP_XMAX_COMMITTED;
if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
return true;
return false; /* updated by other */
}
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: heapam.h,v 1.39 1998/11/27 19:33:31 vadim Exp $ * $Id: heapam.h,v 1.40 1998/12/15 12:46:44 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -42,6 +42,7 @@ typedef struct HeapAccessStatisticsData ...@@ -42,6 +42,7 @@ typedef struct HeapAccessStatisticsData
int global_insert; int global_insert;
int global_delete; int global_delete;
int global_replace; int global_replace;
int global_mark4update;
int global_markpos; int global_markpos;
int global_restrpos; int global_restrpos;
int global_BufferGetRelation; int global_BufferGetRelation;
...@@ -64,6 +65,7 @@ typedef struct HeapAccessStatisticsData ...@@ -64,6 +65,7 @@ typedef struct HeapAccessStatisticsData
int local_insert; int local_insert;
int local_delete; int local_delete;
int local_replace; int local_replace;
int local_mark4update;
int local_markpos; int local_markpos;
int local_restrpos; int local_restrpos;
int local_BufferGetRelation; int local_BufferGetRelation;
...@@ -253,9 +255,10 @@ extern void heap_endscan(HeapScanDesc scan); ...@@ -253,9 +255,10 @@ extern void heap_endscan(HeapScanDesc scan);
extern HeapTuple heap_getnext(HeapScanDesc scandesc, int backw); extern HeapTuple heap_getnext(HeapScanDesc scandesc, int backw);
extern void heap_fetch(Relation relation, Snapshot snapshot, HeapTuple tup, Buffer *userbuf); extern void heap_fetch(Relation relation, Snapshot snapshot, HeapTuple tup, Buffer *userbuf);
extern Oid heap_insert(Relation relation, HeapTuple tup); extern Oid heap_insert(Relation relation, HeapTuple tup);
extern int heap_delete(Relation relation, ItemPointer tid); extern int heap_delete(Relation relation, ItemPointer tid, ItemPointer ctid);
extern int heap_replace(Relation relation, ItemPointer otid, extern int heap_replace(Relation relation, ItemPointer otid, HeapTuple tup,
HeapTuple tup); ItemPointer ctid);
extern int heap_mark4update(Relation relation, HeapTuple tup, Buffer *userbuf);
extern void heap_markpos(HeapScanDesc scan); extern void heap_markpos(HeapScanDesc scan);
extern void heap_restrpos(HeapScanDesc scan); extern void heap_restrpos(HeapScanDesc scan);
...@@ -281,9 +284,4 @@ HeapTuple heap_addheader(uint32 natts, int structlen, char *structure); ...@@ -281,9 +284,4 @@ HeapTuple heap_addheader(uint32 natts, int structlen, char *structure);
extern void PrintHeapAccessStatistics(HeapAccessStatistics stats); extern void PrintHeapAccessStatistics(HeapAccessStatistics stats);
extern void initam(void); extern void initam(void);
/* hio.c */
extern void RelationPutHeapTuple(Relation relation, BlockNumber blockIndex,
HeapTuple tuple);
extern void RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple);
#endif /* HEAPAM_H */ #endif /* HEAPAM_H */
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: hio.h,v 1.8 1998/09/01 04:34:13 momjian Exp $ * $Id: hio.h,v 1.9 1998/12/15 12:46:45 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -17,8 +17,8 @@ ...@@ -17,8 +17,8 @@
#include <utils/rel.h> #include <utils/rel.h>
extern void RelationPutHeapTuple(Relation relation, BlockNumber blockIndex, extern void RelationPutHeapTuple(Relation relation, Buffer buffer,
HeapTuple tuple); HeapTuple tuple);
extern void RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple); extern void RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple);
#endif /* HIO_H */ #endif /* HIO_H */
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: htup.h,v 1.11 1998/11/27 19:33:31 vadim Exp $ * $Id: htup.h,v 1.12 1998/12/15 12:46:46 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -116,6 +116,7 @@ typedef HeapTupleData *HeapTuple; ...@@ -116,6 +116,7 @@ typedef HeapTupleData *HeapTuple;
#define HEAP_XMIN_INVALID 0x0200 /* t_xmin invalid/aborted */ #define HEAP_XMIN_INVALID 0x0200 /* t_xmin invalid/aborted */
#define HEAP_XMAX_COMMITTED 0x0400 /* t_xmax committed */ #define HEAP_XMAX_COMMITTED 0x0400 /* t_xmax committed */
#define HEAP_XMAX_INVALID 0x0800 /* t_xmax invalid/aborted */ #define HEAP_XMAX_INVALID 0x0800 /* t_xmax invalid/aborted */
#define HEAP_MARKED_FOR_UPDATE 0x1000 /* marked for UPDATE */
#define HEAP_XACT_MASK 0x0F00 /* */ #define HEAP_XACT_MASK 0x0F00 /* */
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: xact.h,v 1.17 1998/10/08 18:30:23 momjian Exp $ * $Id: xact.h,v 1.18 1998/12/15 12:46:47 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -38,6 +38,8 @@ typedef struct TransactionStateData ...@@ -38,6 +38,8 @@ typedef struct TransactionStateData
#define XACT_REPEATABLE_READ 2 /* not implemented */ #define XACT_REPEATABLE_READ 2 /* not implemented */
#define XACT_SERIALIZED 3 #define XACT_SERIALIZED 3
extern int XactIsoLevel;
/* ---------------- /* ----------------
* transaction states * transaction states
* ---------------- * ----------------
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: pg_am.h,v 1.9 1998/09/01 04:34:47 momjian Exp $ * $Id: pg_am.h,v 1.10 1998/12/15 12:46:49 vadim Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -106,6 +106,7 @@ DESCR(""); ...@@ -106,6 +106,7 @@ DESCR("");
#define BTREE_AM_OID 403 #define BTREE_AM_OID 403
DATA(insert OID = 405 ( hash PGUID "o" 1 1 hashgettuple hashinsert hashdelete - - - - hashbeginscan hashrescan hashendscan hashmarkpos hashrestrpos - - hashbuild - - )); DATA(insert OID = 405 ( hash PGUID "o" 1 1 hashgettuple hashinsert hashdelete - - - - hashbeginscan hashrescan hashendscan hashmarkpos hashrestrpos - - hashbuild - - ));
DESCR(""); DESCR("");
#define HASH_AM_OID 405
DATA(insert OID = 783 ( gist PGUID "o" 100 7 gistgettuple gistinsert gistdelete - - - - gistbeginscan gistrescan gistendscan gistmarkpos gistrestrpos - - gistbuild - - )); DATA(insert OID = 783 ( gist PGUID "o" 100 7 gistgettuple gistinsert gistdelete - - - - gistbeginscan gistrescan gistendscan gistmarkpos gistrestrpos - - gistbuild - - ));
DESCR(""); DESCR("");
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: pg_class.h,v 1.25 1998/09/10 15:32:31 vadim Exp $ * $Id: pg_class.h,v 1.26 1998/12/15 12:46:50 vadim Exp $
* *
* NOTES * NOTES
* ``pg_relation'' is being replaced by ``pg_class''. currently * ``pg_relation'' is being replaced by ``pg_class''. currently
...@@ -144,6 +144,8 @@ DATA(insert OID = 1264 ( pg_variable 90 PGUID 0 0 0 f t s 2 0 0 0 0 0 f f _n ...@@ -144,6 +144,8 @@ DATA(insert OID = 1264 ( pg_variable 90 PGUID 0 0 0 f t s 2 0 0 0 0 0 f f _n
DESCR(""); DESCR("");
DATA(insert OID = 1269 ( pg_log 99 PGUID 0 0 0 f t s 1 0 0 0 0 0 f f _null_ )); DATA(insert OID = 1269 ( pg_log 99 PGUID 0 0 0 f t s 1 0 0 0 0 0 f f _null_ ));
DESCR(""); DESCR("");
DATA(insert OID = 376 ( pg_xactlock 0 PGUID 0 0 0 f t s 1 0 0 0 0 0 f f _null_ ));
DESCR("");
DATA(insert OID = 1215 ( pg_attrdef 109 PGUID 0 0 0 t t r 4 0 0 0 0 0 f f _null_ )); DATA(insert OID = 1215 ( pg_attrdef 109 PGUID 0 0 0 t t r 4 0 0 0 0 0 f f _null_ ));
DESCR(""); DESCR("");
DATA(insert OID = 1216 ( pg_relcheck 110 PGUID 0 0 0 t t r 4 0 0 0 0 0 f f _null_ )); DATA(insert OID = 1216 ( pg_relcheck 110 PGUID 0 0 0 t t r 4 0 0 0 0 0 f f _null_ ));
...@@ -164,6 +166,9 @@ DESCR(""); ...@@ -164,6 +166,9 @@ DESCR("");
#define RelOid_pg_relcheck 1216 #define RelOid_pg_relcheck 1216
#define RelOid_pg_trigger 1219 #define RelOid_pg_trigger 1219
/* Xact lock pseudo-table */
#define XactLockTableId 376
#define RELKIND_INDEX 'i' /* secondary index */ #define RELKIND_INDEX 'i' /* secondary index */
#define RELKIND_LOBJECT 'l' /* large objects */ #define RELKIND_LOBJECT 'l' /* large objects */
#define RELKIND_RELATION 'r' /* cataloged heap */ #define RELKIND_RELATION 'r' /* cataloged heap */
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "access/tupdesc.h" #include "access/tupdesc.h"
#include "access/htup.h" #include "access/htup.h"
#include "nodes/parsenodes.h" #include "nodes/parsenodes.h"
#include "nodes/execnodes.h"
#include "utils/rel.h" #include "utils/rel.h"
typedef uint32 TriggerEvent; typedef uint32 TriggerEvent;
...@@ -65,9 +66,9 @@ extern void RelationRemoveTriggers(Relation rel); ...@@ -65,9 +66,9 @@ extern void RelationRemoveTriggers(Relation rel);
extern HeapTuple ExecBRInsertTriggers(Relation rel, HeapTuple tuple); extern HeapTuple ExecBRInsertTriggers(Relation rel, HeapTuple tuple);
extern void ExecARInsertTriggers(Relation rel, HeapTuple tuple); extern void ExecARInsertTriggers(Relation rel, HeapTuple tuple);
extern bool ExecBRDeleteTriggers(Relation rel, ItemPointer tupleid); extern bool ExecBRDeleteTriggers(EState *estate, ItemPointer tupleid);
extern void ExecARDeleteTriggers(Relation rel, ItemPointer tupleid); extern void ExecARDeleteTriggers(EState *estate, ItemPointer tupleid);
extern HeapTuple ExecBRUpdateTriggers(Relation rel, ItemPointer tupleid, HeapTuple tuple); extern HeapTuple ExecBRUpdateTriggers(EState *estate, ItemPointer tupleid, HeapTuple tuple);
extern void ExecARUpdateTriggers(Relation rel, ItemPointer tupleid, HeapTuple tuple); extern void ExecARUpdateTriggers(EState *estate, ItemPointer tupleid, HeapTuple tuple);
#endif /* TRIGGER_H */ #endif /* TRIGGER_H */
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: buf_internals.h,v 1.26 1998/09/01 04:38:10 momjian Exp $ * $Id: buf_internals.h,v 1.27 1998/12/15 12:46:55 vadim Exp $
* *
* NOTE * NOTE
* If BUFFERPAGE0 is defined, then 0 will be used as a * If BUFFERPAGE0 is defined, then 0 will be used as a
...@@ -83,32 +83,6 @@ struct buftag ...@@ -83,32 +83,6 @@ struct buftag
* Dbname, relname, dbid, and relid are enough to determine where * Dbname, relname, dbid, and relid are enough to determine where
* to put the buffer, for all storage managers. * to put the buffer, for all storage managers.
*/ */
#define PADDED_SBUFDESC_SIZE 128
/* DO NOT CHANGE THIS NEXT STRUCTURE:
It is used only to get padding information for the real sbufdesc structure
It should match the sbufdesc structure exactly except for a missing sb_pad
*/
struct sbufdesc_unpadded
{
Buffer freeNext;
Buffer freePrev;
SHMEM_OFFSET data;
BufferTag tag;
int buf_id;
BufFlags flags;
unsigned refcount;
#ifdef HAS_TEST_AND_SET
slock_t io_in_progress_lock;
#endif /* HAS_TEST_AND_SET */
char sb_dbname[NAMEDATALEN];
/* NOTE NO PADDING OF THE MEMBER HERE */
char sb_relname[NAMEDATALEN];
};
/* THE REAL STRUCTURE - the structure above must match it, minus sb_pad */
struct sbufdesc struct sbufdesc
{ {
Buffer freeNext; /* link for freelist chain */ Buffer freeNext; /* link for freelist chain */
...@@ -125,31 +99,25 @@ struct sbufdesc ...@@ -125,31 +99,25 @@ struct sbufdesc
#ifdef HAS_TEST_AND_SET #ifdef HAS_TEST_AND_SET
/* can afford a dedicated lock if test-and-set locks are available */ /* can afford a dedicated lock if test-and-set locks are available */
slock_t io_in_progress_lock; slock_t io_in_progress_lock;
slock_t cntx_lock; /* to lock access to page context */
#endif /* HAS_TEST_AND_SET */ #endif /* HAS_TEST_AND_SET */
unsigned r_locks; /* # of shared locks */
bool ri_lock; /* read-intent lock */
bool w_lock; /* context exclusively locked */
char sb_dbname[NAMEDATALEN]; /* name of db in which buf belongs */ char sb_dbname[NAMEDATALEN]; /* name of db in which buf belongs */
char sb_relname[NAMEDATALEN];/* name of reln */
/*
* I padded this structure to a power of 2 (PADDED_SBUFDESC_SIZE)
* because BufferDescriptorGetBuffer is called a billion times and it
* does an C pointer subtraction (i.e., "x - y" -> array index of x
* relative to y, which is calculated using division by struct size).
* Integer ".div" hits you for 35 cycles, as opposed to a 1-cycle
* "sra" ... this hack cut 10% off of the time to create the Wisconsin
* database! It eats up more shared memory, of course, but we're
* (allegedly) going to make some of these types bigger soon anyway...
* -pma 1/2/93
*/
/*
* please, don't take the sizeof() this member and use it for
* something important
*/
char sb_relname[NAMEDATALEN + /* name of reln */
PADDED_SBUFDESC_SIZE - sizeof(struct sbufdesc_unpadded)];
}; };
/*
* Buffer lock infos in BufferLocks below.
* We have to free these locks in elog(ERROR)...
*/
#define BL_IO_IN_PROGRESS (1 << 0) /* unimplemented */
#define BL_R_LOCK (1 << 1)
#define BL_RI_LOCK (1 << 2)
#define BL_W_LOCK (1 << 3)
/* /*
* mao tracing buffer allocation * mao tracing buffer allocation
*/ */
...@@ -201,6 +169,7 @@ extern BufferDesc *BufferDescriptors; ...@@ -201,6 +169,7 @@ extern BufferDesc *BufferDescriptors;
extern BufferBlock BufferBlocks; extern BufferBlock BufferBlocks;
extern long *PrivateRefCount; extern long *PrivateRefCount;
extern long *LastRefCount; extern long *LastRefCount;
extern bits8 *BufferLocks;
extern long *CommitInfoNeedsSave; extern long *CommitInfoNeedsSave;
extern SPINLOCK BufMgrLock; extern SPINLOCK BufMgrLock;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: bufmgr.h,v 1.23 1998/10/08 18:30:43 momjian Exp $ * $Id: bufmgr.h,v 1.24 1998/12/15 12:46:56 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -73,6 +73,14 @@ extern int ShowPinTrace; ...@@ -73,6 +73,14 @@ extern int ShowPinTrace;
#define BUFFER_FLUSH_WRITE 0 /* immediate write */ #define BUFFER_FLUSH_WRITE 0 /* immediate write */
#define BUFFER_LATE_WRITE 1 /* delayed write: mark as DIRTY */ #define BUFFER_LATE_WRITE 1 /* delayed write: mark as DIRTY */
/*
* Buffer context lock modes
*/
#define BUFFER_LOCK_UNLOCK 0
#define BUFFER_LOCK_SHARE 1
#define BUFFER_LOCK_EXCLUSIVE 2
/* /*
* BufferIsValid -- * BufferIsValid --
* True iff the refcnt of the local buffer is > 0 * True iff the refcnt of the local buffer is > 0
...@@ -155,4 +163,7 @@ extern void BufferRefCountRestore(int *refcountsave); ...@@ -155,4 +163,7 @@ extern void BufferRefCountRestore(int *refcountsave);
extern int SetBufferWriteMode(int mode); extern int SetBufferWriteMode(int mode);
extern void SetBufferCommitInfoNeedsSave(Buffer buffer); extern void SetBufferCommitInfoNeedsSave(Buffer buffer);
extern void UnlockBuffers(void);
extern void LockBuffer(Buffer buffer, int mode);
#endif /* !defined(BufMgrIncluded) */ #endif /* !defined(BufMgrIncluded) */
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: ipc.h,v 1.30 1998/09/01 04:38:16 momjian Exp $ * $Id: ipc.h,v 1.31 1998/12/15 12:46:57 vadim Exp $
* *
* NOTES * NOTES
* This file is very architecture-specific. This stuff should actually * This file is very architecture-specific. This stuff should actually
...@@ -186,6 +186,8 @@ typedef enum _LockId_ ...@@ -186,6 +186,8 @@ typedef enum _LockId_
((key == PrivateIPCKey) ? key : 11 + (key)) ((key == PrivateIPCKey) ? key : 11 + (key))
#define IPCKeyGetWaitIOSemaphoreKey(key) \ #define IPCKeyGetWaitIOSemaphoreKey(key) \
((key == PrivateIPCKey) ? key : 12 + (key)) ((key == PrivateIPCKey) ? key : 12 + (key))
#define IPCKeyGetWaitCLSemaphoreKey(key) \
((key == PrivateIPCKey) ? key : 13 + (key))
/* -------------------------- /* --------------------------
* NOTE: This macro must always give the highest numbered key as every backend * NOTE: This macro must always give the highest numbered key as every backend
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: lmgr.h,v 1.15 1998/09/01 04:38:23 momjian Exp $ * $Id: lmgr.h,v 1.16 1998/12/15 12:46:57 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -17,64 +17,48 @@ ...@@ -17,64 +17,48 @@
#include <utils/rel.h> #include <utils/rel.h>
#include <catalog/catname.h> #include <catalog/catname.h>
/* #define AccessShareLock 1 /* SELECT */
* This was moved from pladt.h for the new lock manager. Want to obsolete #define RowShareLock 2 /* SELECT FOR UPDATE */
* all of the old code. #define RowExclusiveLock 3 /* INSERT, UPDATE, DELETE */
*/ #define ShareLock 4
#define ShareRowExclusiveLock 5
#define ExclusiveLock 6
#define AccessExclusiveLock 7
#define ExtendLock 8
extern LOCKMETHOD LockTableId;
typedef struct LockRelId typedef struct LockRelId
{ {
Oid relId; /* a relation identifier */ Oid relId; /* a relation identifier */
Oid dbId; /* a database identifier */ Oid dbId; /* a database identifier */
} LockRelId; } LockRelId;
#ifdef LowLevelLocking
typedef struct LockInfoData typedef struct LockInfoData
{ {
LockRelId lockRelId; LockRelId lockRelId;
bool lockHeld[MAX_LOCKMODES]; /* on table level */
} LockInfoData; } LockInfoData;
#else
typedef struct LockInfoData
{
LockRelId lockRelId;
} LockInfoData;
#endif
typedef LockInfoData *LockInfo; typedef LockInfoData *LockInfo;
#define LockInfoIsValid(lockinfo) PointerIsValid(lockinfo) #define LockInfoIsValid(lockinfo) PointerIsValid(lockinfo)
extern LOCKMETHOD InitLockTable(void);
extern void RelationInitLockInfo(Relation relation); extern void RelationInitLockInfo(Relation relation);
extern void RelationSetLockForDescriptorOpen(Relation relation);
extern void RelationSetLockForRead(Relation relation);
extern void RelationUnsetLockForRead(Relation relation);
extern void RelationSetLockForWrite(Relation relation);
extern void RelationUnsetLockForWrite(Relation relation);
/* used in vaccum.c */ extern void LockRelation(Relation relation, LOCKMODE lockmode);
extern void RelationSetLockForWritePage(Relation relation, extern void UnlockRelation(Relation relation, LOCKMODE lockmode);
ItemPointer itemPointer);
/* used in nbtpage.c, hashpage.c */ /* this is for indices */
extern void RelationSetSingleWLockPage(Relation relation, extern void LockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode);
ItemPointer itemPointer); extern void UnlockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode);
extern void RelationUnsetSingleWLockPage(Relation relation,
ItemPointer itemPointer);
extern void RelationSetSingleRLockPage(Relation relation,
ItemPointer itemPointer);
extern void RelationUnsetSingleRLockPage(Relation relation,
ItemPointer itemPointer);
extern void RelationSetRIntentLock(Relation relation);
extern void RelationUnsetRIntentLock(Relation relation);
extern void RelationSetWIntentLock(Relation relation);
extern void RelationUnsetWIntentLock(Relation relation);
/* single.c */ /* and this is for transactions */
extern bool SingleLockReln(LockInfo lockinfo, LOCKMODE lockmode, int action); extern void XactLockTableInsert(TransactionId xid);
extern bool SingleLockPage(LockInfo lockinfo, ItemPointer tidPtr, extern void XactLockTableDelete(TransactionId xid);
LOCKMODE lockmode, int action); extern void XactLockTableWait(TransactionId xid);
/* proc.c */ /* proc.c */
extern void InitProcGlobal(IPCKey key); extern void InitProcGlobal(IPCKey key);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: lock.h,v 1.19 1998/10/08 18:30:45 momjian Exp $ * $Id: lock.h,v 1.20 1998/12/15 12:46:58 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -42,11 +42,7 @@ typedef int LOCKMODE; ...@@ -42,11 +42,7 @@ typedef int LOCKMODE;
typedef int LOCKMETHOD; typedef int LOCKMETHOD;
/* MAX_LOCKMODES cannot be larger than the bits in MASK */ /* MAX_LOCKMODES cannot be larger than the bits in MASK */
#ifdef LowLevelLocking
#define MAX_LOCKMODES 9 #define MAX_LOCKMODES 9
#else
#define MAX_LOCKMODES 6
#endif
/* /*
* MAX_LOCK_METHODS corresponds to the number of spin locks allocated in * MAX_LOCK_METHODS corresponds to the number of spin locks allocated in
...@@ -69,7 +65,11 @@ typedef struct LTAG ...@@ -69,7 +65,11 @@ typedef struct LTAG
{ {
Oid relId; Oid relId;
Oid dbId; Oid dbId;
ItemPointerData tupleId; union
{
BlockNumber blkno;
TransactionId xid;
} objId;
uint16 lockmethod; /* needed by user locks */ uint16 lockmethod; /* needed by user locks */
} LOCKTAG; } LOCKTAG;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: proc.h,v 1.15 1998/09/01 04:38:31 momjian Exp $ * $Id: proc.h,v 1.16 1998/12/15 12:46:59 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -44,11 +44,9 @@ typedef struct proc ...@@ -44,11 +44,9 @@ typedef struct proc
TransactionId xid; /* transaction currently being executed by TransactionId xid; /* transaction currently being executed by
* this proc */ * this proc */
#ifdef LowLevelLocking
TransactionId xmin; /* minimal running XID as it was when we TransactionId xmin; /* minimal running XID as it was when we
* were starting our xact: vacuum must not * were starting our xact: vacuum must not
* remove tuples deleted by xid >= xmin ! */ * remove tuples deleted by xid >= xmin ! */
#endif
LOCK *waitLock; /* Lock we're sleeping on */ LOCK *waitLock; /* Lock we're sleeping on */
int token; /* info for proc wakeup routines */ int token; /* info for proc wakeup routines */
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/include/storage/s_lock.h,v 1.56 1998/10/31 02:06:08 momjian Exp $ * $Header: /cvsroot/pgsql/src/include/storage/s_lock.h,v 1.57 1998/12/15 12:46:59 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -68,6 +68,8 @@ ...@@ -68,6 +68,8 @@
#include "storage/ipc.h" #include "storage/ipc.h"
extern void s_lock_sleep(unsigned spin);
#if defined(HAS_TEST_AND_SET) #if defined(HAS_TEST_AND_SET)
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment