Commit e3a1ab76 authored by Vadim B. Mikheev's avatar Vadim B. Mikheev

READ COMMITTED isolevel is implemented and is default now.

parent 3e2f87f3
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.39 1998/12/15 12:45:13 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.40 1999/01/29 09:22:51 vadim Exp $
*
*
* INTERFACE ROUTINES
......@@ -1373,6 +1373,7 @@ l3:
if (result != HeapTupleMayBeUpdated)
{
Assert(result == HeapTupleSelfUpdated || result == HeapTupleUpdated);
tuple->t_self = tuple->t_data->t_ctid;
LockBuffer(*buffer, BUFFER_LOCK_UNLOCK);
return result;
}
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.32 1998/12/15 12:45:20 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.33 1999/01/29 09:22:52 vadim Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -134,6 +134,7 @@ l1:
* If this tuple is being updated by other transaction
* then we have to wait for its commit/abort.
*/
ReleaseBuffer(buffer);
if (TransactionIdIsValid(xwait))
{
if (nbuf != InvalidBuffer)
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.28 1998/12/18 09:10:18 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.29 1999/01/29 09:22:53 vadim Exp $
*
* NOTES
* Transaction aborts can now occur two ways:
......@@ -194,7 +194,7 @@ TransactionStateData CurrentTransactionStateData = {
TransactionState CurrentTransactionState =
&CurrentTransactionStateData;
int DefaultXactIsoLevel = XACT_SERIALIZABLE;
int DefaultXactIsoLevel = XACT_READ_COMMITTED;
int XactIsoLevel;
/* ----------------
......
......@@ -28,6 +28,7 @@
#include "utils/inval.h"
#include "utils/builtins.h"
#include "utils/syscache.h"
#include "executor/executor.h"
#ifndef NO_SECURITY
#include "miscadmin.h"
......@@ -790,6 +791,8 @@ ExecARUpdateTriggers(EState *estate, ItemPointer tupleid, HeapTuple newtuple)
return;
}
extern TupleTableSlot *EvalPlanQual(EState *estate, Index rti, ItemPointer tid);
static HeapTuple
GetTupleForTrigger(EState *estate, ItemPointer tid, bool before)
{
......@@ -806,6 +809,7 @@ GetTupleForTrigger(EState *estate, ItemPointer tid, bool before)
* mark tuple for update
*/
tuple.t_self = *tid;
ltrmark:;
test = heap_mark4update(relation, &tuple, &buffer);
switch (test)
{
......@@ -820,8 +824,23 @@ GetTupleForTrigger(EState *estate, ItemPointer tid, bool before)
ReleaseBuffer(buffer);
if (XactIsoLevel == XACT_SERIALIZABLE)
elog(ERROR, "Can't serialize access due to concurrent update");
else
elog(ERROR, "Isolation level %u is not supported", XactIsoLevel);
else if (!(ItemPointerEquals(&(tuple.t_self), tid)))
{
TupleTableSlot *slot = EvalPlanQual(estate,
estate->es_result_relation_info->ri_RangeTableIndex,
&(tuple.t_self));
if (!(TupIsNull(slot)))
{
*tid = tuple.t_self;
goto ltrmark;
}
}
/*
* if tuple was deleted or PlanQual failed
* for updated tuple - we have not process
* this tuple!
*/
return(NULL);
default:
......
This diff is collapsed.
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.29 1998/11/27 19:52:03 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.30 1999/01/29 09:22:58 vadim Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -109,6 +109,40 @@ IndexNext(IndexScan *node)
heapRelation = scanstate->css_currentRelation;
numIndices = indexstate->iss_NumIndices;
slot = scanstate->css_ScanTupleSlot;
/*
* Check if we are evaluating PlanQual for tuple of this relation.
* Additional checking is not good, but no other way for now.
* We could introduce new nodes for this case and handle
* IndexScan --> NewNode switching in Init/ReScan plan...
*/
if (estate->es_evTuple != NULL &&
estate->es_evTuple[node->scan.scanrelid - 1] != NULL)
{
int iptr;
slot->ttc_buffer = InvalidBuffer;
slot->ttc_shouldFree = false;
if (estate->es_evTupleNull[node->scan.scanrelid - 1])
{
slot->val = NULL; /* must not free tuple! */
return (slot);
}
slot->val = estate->es_evTuple[node->scan.scanrelid - 1];
for (iptr = 0; iptr < numIndices; iptr++)
{
scanstate->cstate.cs_ExprContext->ecxt_scantuple = slot;
if (ExecQual(nth(iptr, node->indxqualorig),
scanstate->cstate.cs_ExprContext))
break;
}
if (iptr == numIndices) /* would not be returned by indices */
slot->val = NULL;
/* Flag for the next call that no more tuples */
estate->es_evTupleNull[node->scan.scanrelid - 1] = true;
return (slot);
}
tuple = &(indexstate->iss_htup);
/* ----------------
......@@ -262,6 +296,14 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
numScanKeys = indexstate->iss_NumScanKeys;
indexstate->iss_IndexPtr = 0;
/* If this is re-scanning of PlanQual ... */
if (estate->es_evTuple != NULL &&
estate->es_evTuple[node->scan.scanrelid - 1] != NULL)
{
estate->es_evTupleNull[node->scan.scanrelid - 1] = false;
return;
}
/* it's possible in subselects */
if (exprCtxt == NULL)
exprCtxt = node->scan.scanstate->cstate.cs_ExprContext;
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeSeqscan.c,v 1.15 1998/09/25 13:38:32 thomas Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/nodeSeqscan.c,v 1.16 1999/01/29 09:22:58 vadim Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -64,6 +64,34 @@ SeqNext(SeqScan *node)
scanstate = node->scanstate;
scandesc = scanstate->css_currentScanDesc;
direction = estate->es_direction;
slot = scanstate->css_ScanTupleSlot;
/*
* Check if we are evaluating PlanQual for tuple of this relation.
* Additional checking is not good, but no other way for now.
* We could introduce new nodes for this case and handle
* SeqScan --> NewNode switching in Init/ReScan plan...
*/
if (estate->es_evTuple != NULL &&
estate->es_evTuple[node->scanrelid - 1] != NULL)
{
slot->ttc_buffer = InvalidBuffer;
slot->ttc_shouldFree = false;
if (estate->es_evTupleNull[node->scanrelid - 1])
{
slot->val = NULL; /* must not free tuple! */
return (slot);
}
slot->val = estate->es_evTuple[node->scanrelid - 1];
/*
* Note that unlike IndexScan, SeqScan never use keys
* in heap_beginscan (and this is very bad) - so, here
* we have not check are keys ok or not.
*/
/* Flag for the next call that no more tuples */
estate->es_evTupleNull[node->scanrelid - 1] = true;
return (slot);
}
/* ----------------
* get the next tuple from the access methods
......@@ -79,7 +107,6 @@ SeqNext(SeqScan *node)
* be pfree()'d.
* ----------------
*/
slot = scanstate->css_ScanTupleSlot;
slot = ExecStoreTuple(tuple,/* tuple to store */
slot, /* slot to store in */
......@@ -374,9 +401,15 @@ ExecSeqReScan(SeqScan *node, ExprContext *exprCtxt, Plan *parent)
outerPlan = outerPlan((Plan *) node);
ExecReScan(outerPlan, exprCtxt, parent);
}
else
else /* otherwise, we are scanning a relation */
{
/* otherwise, we are scanning a relation */
/* If this is re-scanning of PlanQual ... */
if (estate->es_evTuple != NULL &&
estate->es_evTuple[node->scanrelid - 1] != NULL)
{
estate->es_evTupleNull[node->scanrelid - 1] = false;
return;
}
rel = scanstate->css_currentRelation;
scan = scanstate->css_currentScanDesc;
direction = estate->es_direction;
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.55 1999/01/25 18:02:14 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.56 1999/01/29 09:22:59 vadim Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -83,7 +83,6 @@ CopyPlanFields(Plan *from, Plan *newnode)
newnode->plan_size = from->plan_size;
newnode->plan_width = from->plan_width;
newnode->plan_tupperpage = from->plan_tupperpage;
newnode->state = from->state;
newnode->targetlist = copyObject(from->targetlist);
newnode->qual = copyObject(from->qual);
newnode->lefttree = copyObject(from->lefttree);
......@@ -138,7 +137,6 @@ _copyResult(Result *from)
* ----------------
*/
Node_Copy(from, newnode, resconstantqual);
Node_Copy(from, newnode, resstate);
return newnode;
}
......@@ -166,7 +164,6 @@ _copyAppend(Append *from)
Node_Copy(from, newnode, unionrtables);
newnode->inheritrelid = from->inheritrelid;
Node_Copy(from, newnode, inheritrtable);
Node_Copy(from, newnode, appendstate);
return newnode;
}
......@@ -183,7 +180,6 @@ static void
CopyScanFields(Scan *from, Scan *newnode)
{
newnode->scanrelid = from->scanrelid;
Node_Copy(from, newnode, scanstate);
return;
}
......@@ -248,7 +244,6 @@ _copyIndexScan(IndexScan *from)
newnode->indxid = listCopy(from->indxid);
Node_Copy(from, newnode, indxqual);
Node_Copy(from, newnode, indxqualorig);
Node_Copy(from, newnode, indxstate);
return newnode;
}
......@@ -304,12 +299,6 @@ _copyNestLoop(NestLoop *from)
CopyPlanFields((Plan *) from, (Plan *) newnode);
CopyJoinFields((Join *) from, (Join *) newnode);
/* ----------------
* copy remainder of node
* ----------------
*/
Node_Copy(from, newnode, nlstate);
return newnode;
}
......@@ -346,8 +335,6 @@ _copyMergeJoin(MergeJoin *from)
newnode->mergeleftorder[0] = from->mergeleftorder[0];
newnode->mergeleftorder[1] = 0;
Node_Copy(from, newnode, mergestate);
return newnode;
}
......@@ -375,12 +362,9 @@ _copyHashJoin(HashJoin *from)
newnode->hashjoinop = from->hashjoinop;
Node_Copy(from, newnode, hashjoinstate);
newnode->hashjointable = from->hashjointable;
/* both are unused !.. */
newnode->hashjointablekey = from->hashjointablekey;
newnode->hashjointablesize = from->hashjointablesize;
newnode->hashdone = from->hashdone;
return newnode;
}
......@@ -437,12 +421,6 @@ _copyMaterial(Material *from)
CopyPlanFields((Plan *) from, (Plan *) newnode);
CopyTempFields((Temp *) from, (Temp *) newnode);
/* ----------------
* copy remainder of node
* ----------------
*/
Node_Copy(from, newnode, matstate);
return newnode;
}
......@@ -463,14 +441,6 @@ _copySort(Sort *from)
CopyPlanFields((Plan *) from, (Plan *) newnode);
CopyTempFields((Temp *) from, (Temp *) newnode);
/* ----------------
* copy remainder of node
* ----------------
*/
Node_Copy(from, newnode, sortstate);
Node_Copy(from, newnode, psortstate);
newnode->cleaned = from->cleaned;
return newnode;
}
......@@ -490,7 +460,6 @@ _copyGroup(Group *from)
newnode->numCols = from->numCols;
newnode->grpColIdx = palloc(from->numCols * sizeof(AttrNumber));
memcpy(newnode->grpColIdx, from->grpColIdx, from->numCols * sizeof(AttrNumber));
Node_Copy(from, newnode, grpstate);
return newnode;
}
......@@ -507,7 +476,6 @@ _copyAgg(Agg *from)
CopyPlanFields((Plan *) from, (Plan *) newnode);
newnode->aggs = get_agg_tlist_references(newnode);
Node_Copy(from, newnode, aggstate);
return newnode;
}
......@@ -553,7 +521,6 @@ _copyUnique(Unique *from)
else
newnode->uniqueAttr = NULL;
newnode->uniqueAttrNum = from->uniqueAttrNum;
Node_Copy(from, newnode, uniquestate);
return newnode;
}
......@@ -579,9 +546,8 @@ _copyHash(Hash *from)
* ----------------
*/
Node_Copy(from, newnode, hashkey);
Node_Copy(from, newnode, hashstate);
newnode->hashtable = from->hashtable;
/* both are unused !.. */
newnode->hashtablekey = from->hashtablekey;
newnode->hashtablesize = from->hashtablesize;
......@@ -599,7 +565,6 @@ _copySubPlan(SubPlan *from)
newnode->setParam = listCopy(from->setParam);
newnode->parParam = listCopy(from->parParam);
Node_Copy(from, newnode, sublink);
newnode->shutdown = from->shutdown;
return newnode;
}
......@@ -1901,7 +1866,7 @@ copyObject(void *from)
}
break;
default:
elog(NOTICE, "copyObject: don't know how to copy %d", nodeTag(from));
elog(ERROR, "copyObject: don't know how to copy %d", nodeTag(from));
retval = from;
break;
}
......
......@@ -239,7 +239,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/Attic/gram.c,v 2.64 1999/01/26 23:32:04 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/Attic/gram.c,v 2.65 1999/01/29 09:23:02 vadim Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
......@@ -4791,7 +4791,7 @@ static const short yycheck[] = { 3,
-1, -1, -1, -1, -1, -1, -1, 214
};
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
#line 3 "/usr/local/bison/bison.simple"
#line 3 "/usr/share/misc/bison.simple"
/* Skeleton output parser for bison,
Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
......@@ -4984,7 +4984,7 @@ __yy_memcpy (char *to, char *from, int count)
#endif
#endif
#line 196 "/usr/local/bison/bison.simple"
#line 196 "/usr/share/misc/bison.simple"
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
into yyparse. The argument should have type void *.
......@@ -11088,7 +11088,7 @@ case 960:
break;}
}
/* the action file gets copied in in place of this dollarsign */
#line 498 "/usr/local/bison/bison.simple"
#line 498 "/usr/share/misc/bison.simple"
yyvsp -= yylen;
yyssp -= yylen;
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.23 1998/12/18 09:10:39 vadim Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.24 1999/01/29 09:23:12 vadim Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -368,6 +368,7 @@ bool
HeapTupleSatisfiesDirty(HeapTupleHeader tuple)
{
SnapshotDirty->xmin = SnapshotDirty->xmax = InvalidTransactionId;
ItemPointerSetInvalid(&(SnapshotDirty->tid));
if (AMI_OVERRIDE)
return true;
......@@ -413,6 +414,7 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple)
{
if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
return true;
SnapshotDirty->tid = tuple->t_ctid;
return false; /* updated by other */
}
......@@ -437,6 +439,7 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple)
if (tuple->t_infomask & HEAP_MARKED_FOR_UPDATE)
return true;
SnapshotDirty->tid = tuple->t_ctid;
return false; /* updated by other */
}
......
......@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: execnodes.h,v 1.21 1999/01/25 12:01:19 vadim Exp $
* $Id: execnodes.h,v 1.22 1999/01/29 09:23:13 vadim Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -194,21 +194,27 @@ typedef struct JunkFilter
*/
typedef struct EState
{
NodeTag type;
ScanDirection es_direction;
Snapshot es_snapshot;
List *es_range_table;
RelationInfo *es_result_relation_info;
Relation es_into_relation_descriptor;
ParamListInfo es_param_list_info;
ParamExecData *es_param_exec_vals; /* this is for subselects */
int es_BaseId;
TupleTable es_tupleTable;
JunkFilter *es_junkFilter;
int *es_refcount;
uint32 es_processed; /* # of tuples processed */
Oid es_lastoid; /* last oid processed (by INSERT) */
List *es_rowMark; /* not good place, but there is no other */
NodeTag type;
ScanDirection es_direction;
Snapshot es_snapshot;
List *es_range_table;
RelationInfo *es_result_relation_info;
Relation es_into_relation_descriptor;
ParamListInfo es_param_list_info;
ParamExecData *es_param_exec_vals; /* this is for subselects */
int es_BaseId;
TupleTable es_tupleTable;
JunkFilter *es_junkFilter;
int *es_refcount;
uint32 es_processed; /* # of tuples processed */
Oid es_lastoid; /* last oid processed (by INSERT) */
List *es_rowMark; /* not good place, but there is no other */
/* Below is to re-evaluate plan qual in READ COMMITTED mode */
struct Plan *es_origPlan;
Pointer es_evalPlanQual;
bool *es_evTupleNull;
HeapTuple *es_evTuple;
bool es_useEvalPlan;
} EState;
/* ----------------
......
......@@ -7,7 +7,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: tqual.h,v 1.18 1998/12/18 09:09:55 vadim Exp $
* $Id: tqual.h,v 1.19 1999/01/29 09:23:17 vadim Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -22,6 +22,7 @@ typedef struct SnapshotData
TransactionId xmax; /* XID >= xmax are invisible to me */
uint32 xcnt; /* # of xact below */
TransactionId *xip; /* array of xacts in progress */
ItemPointerData tid; /* required for Dirty snapshot -:( */
} SnapshotData;
typedef SnapshotData *Snapshot;
......
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