summaryrefslogtreecommitdiff
path: root/src/backend/executor
diff options
context:
space:
mode:
authorVadim B. Mikheev <vadim4o@yahoo.com>1998-12-15 12:47:01 +0000
committerVadim B. Mikheev <vadim4o@yahoo.com>1998-12-15 12:47:01 +0000
commit3f7fbf85dc5b42dfd33c803efe6c90533773576a (patch)
treedf8f84075ae7a27fa6b7ec0d063a03898e0b1bbb /src/backend/executor
parentc5a27161a188b235ce3c0afb1b12e8942ac8e963 (diff)
downloadpostgresql-3f7fbf85dc5b42dfd33c803efe6c90533773576a.tar.gz
Initial MVCC code.
New code for locking buffer' context.
Diffstat (limited to 'src/backend/executor')
-rw-r--r--src/backend/executor/execMain.c97
-rw-r--r--src/backend/executor/execUtils.c31
-rw-r--r--src/backend/executor/nodeHash.c10
3 files changed, 92 insertions, 46 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 45be159ae1..712f228534 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -26,7 +26,7 @@
*
*
* 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 @@
/* #include "access/localam.h" */
#include "optimizer/var.h"
#include "access/heapam.h"
+#include "access/xact.h"
#include "catalog/heap.h"
#include "commands/trigger.h"
@@ -421,7 +422,6 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
{
/******************
* if we have a result relation, open it and
-
* initialize the result relation info stuff.
******************
*/
@@ -440,14 +440,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
elog(ERROR, "You can't change sequence relation %s",
resultRelationDesc->rd_rel->relname.data);
- /*
- * 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);
+ LockRelation(resultRelationDesc, RowExclusiveLock);
resultRelationInfo = makeNode(RelationInfo);
resultRelationInfo->ri_RangeTableIndex = resultRelationIndex;
@@ -461,7 +454,8 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
* in the result relation information..
******************
*/
- ExecOpenIndices(resultRelationOid, resultRelationInfo);
+ if (operation != CMD_DELETE)
+ ExecOpenIndices(resultRelationOid, resultRelationInfo);
estate->es_result_relation_info = resultRelationInfo;
}
@@ -1006,8 +1000,10 @@ ExecDelete(TupleTableSlot *slot,
ItemPointer tupleid,
EState *estate)
{
- RelationInfo *resultRelationInfo;
- Relation resultRelationDesc;
+ RelationInfo *resultRelationInfo;
+ Relation resultRelationDesc;
+ ItemPointerData ctid;
+ int result;
/******************
* get the result relation information
@@ -1022,19 +1018,35 @@ ExecDelete(TupleTableSlot *slot,
{
bool dodelete;
- dodelete = ExecBRDeleteTriggers(resultRelationDesc, tupleid);
+ dodelete = ExecBRDeleteTriggers(estate, tupleid);
if (!dodelete) /* "do nothing" */
return;
}
- /******************
+ /*
* delete the tuple
- ******************
*/
- if (heap_delete(resultRelationDesc, /* relation desc */
- tupleid)) /* item pointer to tuple */
- return;
+ result = heap_delete(resultRelationDesc, tupleid, &ctid);
+ switch (result)
+ {
+ 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();
(estate->es_processed)++;
@@ -1054,7 +1066,7 @@ ExecDelete(TupleTableSlot *slot,
/* AFTER ROW DELETE Triggers */
if (resultRelationDesc->trigdesc &&
resultRelationDesc->trigdesc->n_after_row[TRIGGER_EVENT_DELETE] > 0)
- ExecARDeleteTriggers(resultRelationDesc, tupleid);
+ ExecARDeleteTriggers(estate, tupleid);
}
@@ -1075,10 +1087,12 @@ ExecReplace(TupleTableSlot *slot,
EState *estate,
Query *parseTree)
{
- HeapTuple tuple;
- RelationInfo *resultRelationInfo;
- Relation resultRelationDesc;
- int numIndices;
+ HeapTuple tuple;
+ RelationInfo *resultRelationInfo;
+ Relation resultRelationDesc;
+ ItemPointerData ctid;
+ int result;
+ int numIndices;
/******************
* abort the operation if not running transactions
@@ -1117,7 +1131,7 @@ ExecReplace(TupleTableSlot *slot,
{
HeapTuple newtuple;
- newtuple = ExecBRUpdateTriggers(resultRelationDesc, tupleid, tuple);
+ newtuple = ExecBRUpdateTriggers(estate, tupleid, tuple);
if (newtuple == NULL) /* "do nothing" */
return;
@@ -1140,19 +1154,28 @@ ExecReplace(TupleTableSlot *slot,
ExecConstraints("ExecReplace", resultRelationDesc, 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 */
- tupleid, /* item ptr of tuple to replace */
- tuple))
- { /* replacement heap tuple */
- return;
+ result = heap_replace(resultRelationDesc, tupleid, tuple, &ctid);
+ switch (result)
+ {
+ 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_replace", result);
+ return;
}
IncrReplaced();
@@ -1187,7 +1210,7 @@ ExecReplace(TupleTableSlot *slot,
/* AFTER ROW UPDATE Triggers */
if (resultRelationDesc->trigdesc &&
resultRelationDesc->trigdesc->n_after_row[TRIGGER_EVENT_UPDATE] > 0)
- ExecARUpdateTriggers(resultRelationDesc, tupleid, tuple);
+ ExecARUpdateTriggers(estate, tupleid, tuple);
}
#if 0
diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c
index 1af4fcbc88..58dbcd19ef 100644
--- a/src/backend/executor/execUtils.c
+++ b/src/backend/executor/execUtils.c
@@ -7,7 +7,7 @@
*
*
* 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,
indexOid = lfirsti(indexoid);
indexDesc = index_open(indexOid);
if (indexDesc != NULL)
+ {
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)
relationDescs = resultRelationInfo->ri_IndexRelationDescs;
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.
*/
diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index 5f528850ff..5ec45c7c79 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -6,7 +6,7 @@
* 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,
else
heapTuple = (HeapTuple)
LONGALIGN(((char *) curtuple + curtuple->t_len + HEAPTUPLESIZE));
-
- heapTuple->t_data = (HeapTupleHeader)
- ((char *) heapTuple + HEAPTUPLESIZE);
while (heapTuple < (HeapTuple) ABSADDR(bucket->bottom))
{
+ heapTuple->t_data = (HeapTupleHeader)
+ ((char *) heapTuple + HEAPTUPLESIZE);
+
inntuple = ExecStoreTuple(heapTuple, /* tuple to store */
hjstate->hj_HashTupleSlot, /* slot */
InvalidBuffer, /* tuple has no buffer */
@@ -713,8 +713,6 @@ ExecScanHashBucket(HashJoinState *hjstate,
heapTuple = (HeapTuple)
LONGALIGN(((char *) heapTuple + heapTuple->t_len + HEAPTUPLESIZE));
- heapTuple->t_data = (HeapTupleHeader)
- ((char *) heapTuple + HEAPTUPLESIZE);
}
if (firstotuple == NULL)