1
0
mirror of https://github.com/postgres/postgres.git synced 2025-08-30 06:01:21 +03:00

Initial MVCC code.

New code for locking buffer' context.
This commit is contained in:
Vadim B. Mikheev
1998-12-15 12:47:01 +00:00
parent c5a27161a1
commit 3f7fbf85dc
65 changed files with 1391 additions and 1282 deletions

View File

@@ -6,7 +6,7 @@
* Copyright (c) 1994, Regents of the University of California
*
* 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)
TPRINTF(TRACE_NOTIFY, "Async_Listen: %s", relname);
lRel = heap_openr(ListenerRelationName);
RelationSetLockForWrite(lRel);
LockRelation(lRel, AccessExclusiveLock);
tdesc = RelationGetDescr(lRel);
/* Detect whether we are already listening on this relname */
@@ -242,7 +242,7 @@ Async_Listen(char *relname, int pid)
if (alreadyListener)
{
elog(NOTICE, "Async_Listen: We are already listening on %s", relname);
RelationUnsetLockForWrite(lRel);
UnlockRelation(lRel, AccessExclusiveLock);
heap_close(lRel);
return;
}
@@ -267,7 +267,7 @@ Async_Listen(char *relname, int pid)
heap_insert(lRel, newtup);
pfree(newtup);
RelationUnsetLockForWrite(lRel);
UnlockRelation(lRel, AccessExclusiveLock);
heap_close(lRel);
/*
@@ -320,9 +320,9 @@ Async_Unlisten(char *relname, int pid)
if (lTuple != NULL)
{
lRel = heap_openr(ListenerRelationName);
RelationSetLockForWrite(lRel);
heap_delete(lRel, &lTuple->t_self);
RelationUnsetLockForWrite(lRel);
LockRelation(lRel, AccessExclusiveLock);
heap_delete(lRel, &lTuple->t_self, NULL);
UnlockRelation(lRel, AccessExclusiveLock);
heap_close(lRel);
}
/* We do not complain about unlistening something not being listened;
@@ -358,7 +358,7 @@ Async_UnlistenAll()
TPRINTF(TRACE_NOTIFY, "Async_UnlistenAll");
lRel = heap_openr(ListenerRelationName);
RelationSetLockForWrite(lRel);
LockRelation(lRel, AccessExclusiveLock);
tdesc = RelationGetDescr(lRel);
/* Find and delete all entries with my listenerPID */
@@ -369,10 +369,10 @@ Async_UnlistenAll()
sRel = heap_beginscan(lRel, 0, SnapshotNow, 1, key);
while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0)))
heap_delete(lRel, &lTuple->t_self);
heap_delete(lRel, &lTuple->t_self, NULL);
heap_endscan(sRel);
RelationUnsetLockForWrite(lRel);
UnlockRelation(lRel, AccessExclusiveLock);
heap_close(lRel);
}
@@ -463,7 +463,7 @@ AtCommit_Notify()
TPRINTF(TRACE_NOTIFY, "AtCommit_Notify");
lRel = heap_openr(ListenerRelationName);
RelationSetLockForWrite(lRel);
LockRelation(lRel, AccessExclusiveLock);
tdesc = RelationGetDescr(lRel);
sRel = heap_beginscan(lRel, 0, SnapshotNow, 0, (ScanKey) NULL);
@@ -516,7 +516,7 @@ AtCommit_Notify()
* but as far as I can see we should just do it for any
* failure (certainly at least for EPERM too...)
*/
heap_delete(lRel, &lTuple->t_self);
heap_delete(lRel, &lTuple->t_self, NULL);
}
else
#endif
@@ -527,7 +527,7 @@ AtCommit_Notify()
{
rTuple = heap_modifytuple(lTuple, lRel,
value, nulls, repl);
heap_replace(lRel, &lTuple->t_self, rTuple);
heap_replace(lRel, &lTuple->t_self, rTuple, NULL);
}
}
}
@@ -741,7 +741,7 @@ ProcessIncomingNotify(void)
StartTransactionCommand();
lRel = heap_openr(ListenerRelationName);
RelationSetLockForWrite(lRel);
LockRelation(lRel, AccessExclusiveLock);
tdesc = RelationGetDescr(lRel);
/* Scan only entries with my listenerPID */
@@ -772,7 +772,7 @@ ProcessIncomingNotify(void)
NotifyMyFrontEnd(relname, sourcePID);
/* Rewrite the tuple with 0 in notification column */
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);

View File

@@ -7,7 +7,7 @@
*
*
* 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
* The PortalExecutorHeapMemory crap needs to be eliminated
@@ -482,7 +482,7 @@ PerformAddAttribute(char *relationName,
heap_close(attrdesc);
((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 */
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs);

View File

@@ -6,7 +6,7 @@
*
*
* 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)
pfree(typmod);
}
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);
}
@@ -914,7 +928,14 @@ GetIndexRelations(Oid main_relation_oid,
*index_rels = (Relation *) palloc(*n_indices * sizeof(Relation));
for (i = 0, scan = head; i < *n_indices; i++, scan = scan->next)
{
(*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++)
{

View File

@@ -7,7 +7,7 @@
*
*
* 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,
* delays when multiple 'createdb's or 'destroydb's are run simult.
* -mer 7/3/91
*/
RelationSetLockForWrite(dbrel);
LockRelation(dbrel, AccessExclusiveLock);
dbtup = get_pg_dbtup(command, dbname, dbrel);
dbfound = HeapTupleIsValid(dbtup);

View File

@@ -7,7 +7,7 @@
*
*
* 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)
heapRelation = heap_open(relationId);
indexRelation = index_open(indexId);
RelationSetLockForWrite(heapRelation);
LockRelation(heapRelation, ShareLock);
InitIndexStrategy(numberOfAttributes, indexRelation, accessMethodId);

View File

@@ -174,7 +174,7 @@ DropProceduralLanguage(DropPLangStmt *stmt)
}
rel = heap_openr(LanguageRelationName);
heap_delete(rel, &langTup->t_self);
heap_delete(rel, &langTup->t_self, NULL);
pfree(langTup);
heap_close(rel);

View File

@@ -7,7 +7,7 @@
*
*
* 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 */
elog(ERROR, "RemoveOperator: operator '%s': permission denied",
operatorName);
#endif
heap_delete(relation, &tup->t_self);
heap_delete(relation, &tup->t_self, NULL);
}
else
{
@@ -157,7 +157,7 @@ SingleOpOperatorRemove(Oid typeOid)
key[0].sk_attno = attnums[i];
scan = heap_beginscan(rel, 0, SnapshotNow, 1, key);
while (HeapTupleIsValid(tup = heap_getnext(scan, 0)))
heap_delete(rel, &tup->t_self);
heap_delete(rel, &tup->t_self, NULL);
heap_endscan(scan);
}
heap_close(rel);
@@ -268,7 +268,7 @@ RemoveType(char *typeName) /* type name to be removed */
relation = heap_openr(TypeRelationName);
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 */
shadow_type = makeArrayTypeName(typeName);
@@ -282,7 +282,7 @@ RemoveType(char *typeName) /* type name to be removed */
}
typeOid = tup->t_data->t_oid;
heap_delete(relation, &tup->t_self);
heap_delete(relation, &tup->t_self, NULL);
heap_close(relation);
}
@@ -357,7 +357,7 @@ RemoveFunction(char *functionName, /* function name to be removed */
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);
}
@@ -428,7 +428,7 @@ RemoveAggregate(char *aggName, char *aggType)
aggName);
}
}
heap_delete(relation, &tup->t_self);
heap_delete(relation, &tup->t_self, NULL);
heap_close(relation);
}

View File

@@ -7,7 +7,7 @@
*
*
* 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,
newattname, NAMEDATALEN);
attrelation = heap_openr(AttributeRelationName);
heap_replace(attrelation, &oldatttup->t_self, oldatttup);
heap_replace(attrelation, &oldatttup->t_self, oldatttup, NULL);
/* keep system catalog indices current */
CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, irelations);
@@ -248,7 +248,7 @@ renamerel(char *oldrelname, char *newrelname)
/* insert fixed rel tuple */
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 */
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, irelations);

View File

@@ -162,7 +162,7 @@ DefineSequence(CreateSeqStmt *seq)
rel = heap_openr(seq->seqname);
Assert(RelationIsValid(rel));
RelationSetLockForWrite(rel);
LockRelation(rel, AccessExclusiveLock);
tupDesc = RelationGetDescr(rel);
@@ -185,7 +185,7 @@ DefineSequence(CreateSeqStmt *seq)
if (WriteBuffer(buf) == STATUS_ERROR)
elog(ERROR, "DefineSequence: WriteBuffer failed");
RelationUnsetLockForWrite(rel);
UnlockRelation(rel, AccessExclusiveLock);
heap_close(rel);
return;
@@ -200,7 +200,6 @@ nextval(struct varlena * seqin)
SeqTable elm;
Buffer buf;
Form_pg_sequence seq;
ItemPointerData iptr;
int4 incby,
maxv,
minv,
@@ -209,7 +208,7 @@ nextval(struct varlena * seqin)
next,
rescnt = 0;
/* open and WIntentLock sequence */
/* open and AccessShareLock sequence */
elm = init_sequence("nextval", seqname);
pfree(seqname);
@@ -219,7 +218,7 @@ nextval(struct varlena * seqin)
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 */
next = result = seq->last_value;
@@ -282,12 +281,11 @@ nextval(struct varlena * seqin)
seq->last_value = next; /* last fetched number */
seq->is_called = 't';
LockBuffer(buf, BUFFER_LOCK_UNLOCK);
if (WriteBuffer(buf) == STATUS_ERROR)
elog(ERROR, "%s.nextval: WriteBuffer failed", elm->name);
ItemPointerSet(&iptr, 0, FirstOffsetNumber);
RelationUnsetSingleWLockPage(elm->rel, &iptr);
return result;
}
@@ -300,7 +298,7 @@ currval(struct varlena * seqin)
SeqTable elm;
int4 result;
/* open and WIntentLock sequence */
/* open and AccessShareLock sequence */
elm = init_sequence("currval", seqname);
pfree(seqname);
@@ -320,7 +318,6 @@ setval(struct varlena * seqin, int4 next)
SeqTable elm;
Buffer buf;
Form_pg_sequence seq;
ItemPointerData iptr;
#ifndef NO_SECURITY
if (pg_aclcheck(seqname, getpgusername(), ACL_WR) != ACLCHECK_OK)
@@ -328,9 +325,9 @@ setval(struct varlena * seqin, int4 next)
seqname, seqname);
#endif
/* open and WIntentLock sequence */
/* open and AccessShareLock sequence */
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 */
if (seq->cache_value != 1)
@@ -353,27 +350,22 @@ setval(struct varlena * seqin, int4 next)
seq->last_value = next; /* last fetched number */
seq->is_called = 't';
LockBuffer(buf, BUFFER_LOCK_UNLOCK);
if (WriteBuffer(buf) == STATUS_ERROR)
elog(ERROR, "%s.settval: WriteBuffer failed", seqname);
ItemPointerSet(&iptr, 0, FirstOffsetNumber);
RelationUnsetSingleWLockPage(elm->rel, &iptr);
return next;
}
static Form_pg_sequence
read_info(char *caller, SeqTable elm, Buffer *buf)
{
ItemPointerData iptr;
PageHeader page;
ItemId lp;
PageHeader page;
ItemId lp;
HeapTupleData tuple;
sequence_magic *sm;
Form_pg_sequence seq;
ItemPointerSet(&iptr, 0, FirstOffsetNumber);
RelationSetSingleWLockPage(elm->rel, &iptr);
Form_pg_sequence seq;
if (RelationGetNumberOfBlocks(elm->rel) != 1)
elog(ERROR, "%s.%s: invalid number of blocks in sequence",
@@ -383,6 +375,8 @@ read_info(char *caller, SeqTable elm, Buffer *buf)
if (!BufferIsValid(*buf))
elog(ERROR, "%s.%s: ReadBuffer failed", elm->name, caller);
LockBuffer(*buf, BUFFER_LOCK_EXCLUSIVE);
page = (PageHeader) BufferGetPage(*buf);
sm = (sequence_magic *) PageGetSpecialPointer(page);
@@ -439,7 +433,7 @@ init_sequence(char *caller, char *name)
if (!RelationIsValid(temp->rel))
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)
elog(ERROR, "%s.%s: %s is not sequence !", name, caller, name);
@@ -485,7 +479,7 @@ CloseSequences(void)
{
rel = elm->rel;
elm->rel = (Relation) NULL;
RelationUnsetWIntentLock(rel);
UnlockRelation(rel, AccessShareLock);
heap_close(rel);
}
elm = elm->next;

View File

@@ -40,7 +40,7 @@ void RelationBuildTriggers(Relation relation);
void FreeTriggerDesc(Relation relation);
static void DescribeTrigger(TriggerDesc *trigdesc, Trigger *trigger);
static HeapTuple GetTupleForTrigger(Relation relation, ItemPointer tid,
static HeapTuple GetTupleForTrigger(EState *estate, ItemPointer tid,
bool before);
extern GlobalMemory CacheCxt;
@@ -77,7 +77,7 @@ CreateTrigger(CreateTrigStmt *stmt)
if (!RelationIsValid(rel))
elog(ERROR, "CreateTrigger: there is no relation %s", stmt->relname);
RelationSetLockForWrite(rel);
LockRelation(rel, AccessExclusiveLock);
TRIGGER_CLEAR_TYPE(tgtype);
if (stmt->before)
@@ -114,7 +114,7 @@ CreateTrigger(CreateTrigStmt *stmt)
/* Scan pg_trigger */
tgrel = heap_openr(TriggerRelationName);
RelationSetLockForWrite(tgrel);
LockRelation(tgrel, AccessExclusiveLock);
ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgrelid,
F_OIDEQ, RelationGetRelid(rel));
tgscan = heap_beginscan(tgrel, 0, SnapshotNow, 1, &key);
@@ -211,7 +211,7 @@ CreateTrigger(CreateTrigStmt *stmt)
CatalogIndexInsert(idescs, Num_pg_trigger_indices, tgrel, tuple);
CatalogCloseIndices(Num_pg_trigger_indices, idescs);
pfree(tuple);
RelationUnsetLockForWrite(tgrel);
UnlockRelation(tgrel, AccessExclusiveLock);
heap_close(tgrel);
pfree(DatumGetPointer(values[Anum_pg_trigger_tgname - 1]));
@@ -227,7 +227,7 @@ CreateTrigger(CreateTrigStmt *stmt)
pgrel = heap_openr(RelationRelationName);
((Form_pg_class) GETSTRUCT(tuple))->reltriggers = found + 1;
RelationInvalidateHeapTuple(pgrel, tuple);
heap_replace(pgrel, &tuple->t_self, tuple);
heap_replace(pgrel, &tuple->t_self, tuple, NULL);
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs);
CatalogIndexInsert(ridescs, Num_pg_class_indices, pgrel, tuple);
CatalogCloseIndices(Num_pg_class_indices, ridescs);
@@ -267,10 +267,10 @@ DropTrigger(DropTrigStmt *stmt)
if (!RelationIsValid(rel))
elog(ERROR, "DropTrigger: there is no relation %s", stmt->relname);
RelationSetLockForWrite(rel);
LockRelation(rel, AccessExclusiveLock);
tgrel = heap_openr(TriggerRelationName);
RelationSetLockForWrite(tgrel);
LockRelation(tgrel, AccessExclusiveLock);
ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgrelid,
F_OIDEQ, RelationGetRelid(rel));
tgscan = heap_beginscan(tgrel, 0, SnapshotNow, 1, &key);
@@ -280,7 +280,7 @@ DropTrigger(DropTrigStmt *stmt)
if (namestrcmp(&(pg_trigger->tgname), stmt->trigname) == 0)
{
heap_delete(tgrel, &tuple->t_self);
heap_delete(tgrel, &tuple->t_self, NULL);
tgfound++;
}
else
@@ -293,7 +293,7 @@ DropTrigger(DropTrigStmt *stmt)
elog(NOTICE, "DropTrigger: found (and deleted) %d trigger %s on relation %s",
tgfound, stmt->trigname, stmt->relname);
heap_endscan(tgscan);
RelationUnsetLockForWrite(tgrel);
UnlockRelation(tgrel, AccessExclusiveLock);
heap_close(tgrel);
tuple = SearchSysCacheTupleCopy(RELNAME,
@@ -306,7 +306,7 @@ DropTrigger(DropTrigStmt *stmt)
pgrel = heap_openr(RelationRelationName);
((Form_pg_class) GETSTRUCT(tuple))->reltriggers = found;
RelationInvalidateHeapTuple(pgrel, tuple);
heap_replace(pgrel, &tuple->t_self, tuple);
heap_replace(pgrel, &tuple->t_self, tuple, NULL);
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs);
CatalogIndexInsert(ridescs, Num_pg_class_indices, pgrel, tuple);
CatalogCloseIndices(Num_pg_class_indices, ridescs);
@@ -333,17 +333,17 @@ RelationRemoveTriggers(Relation rel)
HeapTuple tup;
tgrel = heap_openr(TriggerRelationName);
RelationSetLockForWrite(tgrel);
LockRelation(tgrel, AccessExclusiveLock);
ScanKeyEntryInitialize(&key, 0, Anum_pg_trigger_tgrelid,
F_OIDEQ, RelationGetRelid(rel));
tgscan = heap_beginscan(tgrel, 0, SnapshotNow, 1, &key);
while (HeapTupleIsValid(tup = heap_getnext(tgscan, 0)))
heap_delete(tgrel, &tup->t_self);
heap_delete(tgrel, &tup->t_self, NULL);
heap_endscan(tgscan);
RelationUnsetLockForWrite(tgrel);
UnlockRelation(tgrel, AccessExclusiveLock);
heap_close(tgrel);
}
@@ -376,7 +376,6 @@ RelationBuildTriggers(Relation relation)
ObjectIdGetDatum(RelationGetRelid(relation)));
tgrel = heap_openr(TriggerRelationName);
RelationSetLockForRead(tgrel);
irel = index_openr(TriggerRelidIndex);
sd = index_beginscan(irel, false, 1, &skey);
@@ -450,7 +449,6 @@ RelationBuildTriggers(Relation relation)
index_endscan(sd);
pfree(sd);
index_close(irel);
RelationUnsetLockForRead(tgrel);
heap_close(tgrel);
/* Build trigdesc */
@@ -657,16 +655,17 @@ ExecARInsertTriggers(Relation rel, HeapTuple trigtuple)
}
bool
ExecBRDeleteTriggers(Relation rel, ItemPointer tupleid)
ExecBRDeleteTriggers(EState *estate, ItemPointer tupleid)
{
TriggerData *SaveTriggerData;
int ntrigs = rel->trigdesc->n_before_row[TRIGGER_EVENT_DELETE];
Trigger **trigger = rel->trigdesc->tg_before_row[TRIGGER_EVENT_DELETE];
HeapTuple trigtuple;
HeapTuple newtuple = NULL;
int i;
Relation rel = estate->es_result_relation_info->ri_RelationDesc;
TriggerData *SaveTriggerData;
int ntrigs = rel->trigdesc->n_before_row[TRIGGER_EVENT_DELETE];
Trigger **trigger = rel->trigdesc->tg_before_row[TRIGGER_EVENT_DELETE];
HeapTuple trigtuple;
HeapTuple newtuple = NULL;
int i;
trigtuple = GetTupleForTrigger(rel, tupleid, true);
trigtuple = GetTupleForTrigger(estate, tupleid, true);
if (trigtuple == NULL)
return false;
@@ -692,15 +691,16 @@ ExecBRDeleteTriggers(Relation rel, ItemPointer tupleid)
}
void
ExecARDeleteTriggers(Relation rel, ItemPointer tupleid)
ExecARDeleteTriggers(EState *estate, ItemPointer tupleid)
{
Relation rel = estate->es_result_relation_info->ri_RelationDesc;
TriggerData *SaveTriggerData;
int ntrigs = rel->trigdesc->n_after_row[TRIGGER_EVENT_DELETE];
Trigger **trigger = rel->trigdesc->tg_after_row[TRIGGER_EVENT_DELETE];
HeapTuple trigtuple;
int i;
trigtuple = GetTupleForTrigger(rel, tupleid, false);
trigtuple = GetTupleForTrigger(estate, tupleid, false);
Assert(trigtuple != NULL);
SaveTriggerData = (TriggerData *) palloc(sizeof(TriggerData));
@@ -722,17 +722,18 @@ ExecARDeleteTriggers(Relation rel, ItemPointer tupleid)
}
HeapTuple
ExecBRUpdateTriggers(Relation rel, ItemPointer tupleid, HeapTuple newtuple)
ExecBRUpdateTriggers(EState *estate, ItemPointer tupleid, HeapTuple newtuple)
{
TriggerData *SaveTriggerData;
int ntrigs = rel->trigdesc->n_before_row[TRIGGER_EVENT_UPDATE];
Trigger **trigger = rel->trigdesc->tg_before_row[TRIGGER_EVENT_UPDATE];
HeapTuple trigtuple;
HeapTuple oldtuple;
HeapTuple intuple = newtuple;
int i;
Relation rel = estate->es_result_relation_info->ri_RelationDesc;
TriggerData *SaveTriggerData;
int ntrigs = rel->trigdesc->n_before_row[TRIGGER_EVENT_UPDATE];
Trigger **trigger = rel->trigdesc->tg_before_row[TRIGGER_EVENT_UPDATE];
HeapTuple trigtuple;
HeapTuple oldtuple;
HeapTuple intuple = newtuple;
int i;
trigtuple = GetTupleForTrigger(rel, tupleid, true);
trigtuple = GetTupleForTrigger(estate, tupleid, true);
if (trigtuple == NULL)
return NULL;
@@ -759,15 +760,16 @@ ExecBRUpdateTriggers(Relation rel, ItemPointer tupleid, HeapTuple newtuple)
}
void
ExecARUpdateTriggers(Relation rel, ItemPointer tupleid, HeapTuple newtuple)
ExecARUpdateTriggers(EState *estate, ItemPointer tupleid, HeapTuple newtuple)
{
Relation rel = estate->es_result_relation_info->ri_RelationDesc;
TriggerData *SaveTriggerData;
int ntrigs = rel->trigdesc->n_after_row[TRIGGER_EVENT_UPDATE];
Trigger **trigger = rel->trigdesc->tg_after_row[TRIGGER_EVENT_UPDATE];
HeapTuple trigtuple;
int i;
trigtuple = GetTupleForTrigger(rel, tupleid, false);
trigtuple = GetTupleForTrigger(estate, tupleid, false);
Assert(trigtuple != NULL);
SaveTriggerData = (TriggerData *) palloc(sizeof(TriggerData));
@@ -789,48 +791,67 @@ ExecARUpdateTriggers(Relation rel, ItemPointer tupleid, HeapTuple newtuple)
}
static HeapTuple
GetTupleForTrigger(Relation relation, ItemPointer tid, bool before)
GetTupleForTrigger(EState *estate, ItemPointer tid, bool before)
{
ItemId lp;
Relation relation = estate->es_result_relation_info->ri_RelationDesc;
HeapTupleData tuple;
HeapTuple result;
PageHeader dp;
Buffer b;
b = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
if (!BufferIsValid(b))
elog(ERROR, "GetTupleForTrigger: failed ReadBuffer");
dp = (PageHeader) BufferGetPage(b);
lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));
Assert(ItemIdIsUsed(lp));
tuple.t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
tuple.t_len = ItemIdGetLength(lp);
tuple.t_self = *tid;
Buffer buffer;
if (before)
{
if (TupleUpdatedByCurXactAndCmd(&tuple))
{
elog(NOTICE, "GetTupleForTrigger: Non-functional delete/update");
ReleaseBuffer(b);
return NULL;
}
int test;
HeapTupleSatisfies(&tuple, relation, b, dp,
false, 0, (ScanKey) NULL);
if (!tuple.t_data)
/*
* mark tuple for update
*/
tuple.t_self = *tid;
test = heap_mark4update(relation, &tuple, &buffer);
switch (test)
{
ReleaseBuffer(b);
elog(ERROR, "GetTupleForTrigger: (am)invalid tid");
case HeapTupleSelfUpdated:
ReleaseBuffer(buffer);
return(NULL);
case HeapTupleMayBeUpdated:
break;
case HeapTupleUpdated:
ReleaseBuffer(buffer);
if (XactIsoLevel == XACT_SERIALIZED)
elog(ERROR, "Serialize access failed due to concurrent update");
else
elog(ERROR, "Isolation level %u is not supported", XactIsoLevel);
return(NULL);
default:
ReleaseBuffer(buffer);
elog(ERROR, "Unknown status %u from heap_mark4update", test);
return(NULL);
}
}
else
{
PageHeader dp;
ItemId lp;
buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
if (!BufferIsValid(buffer))
elog(ERROR, "GetTupleForTrigger: failed ReadBuffer");
dp = (PageHeader) BufferGetPage(buffer);
lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));
Assert(ItemIdIsUsed(lp));
tuple.t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
tuple.t_len = ItemIdGetLength(lp);
tuple.t_self = *tid;
}
result = heap_copytuple(&tuple);
ReleaseBuffer(b);
ReleaseBuffer(buffer);
return result;
}

View File

@@ -5,7 +5,7 @@
*
* 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)
* Secure a write lock on pg_shadow so we can be sure of what the next
* usesysid should be.
*/
RelationSetLockForWrite(pg_shadow_rel);
LockRelation(pg_shadow_rel, AccessExclusiveLock);
scan = heap_beginscan(pg_shadow_rel, false, SnapshotNow, 0, NULL);
while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
@@ -154,7 +154,7 @@ DefineUser(CreateUserStmt *stmt)
if (exists)
{
RelationUnsetLockForWrite(pg_shadow_rel);
UnlockRelation(pg_shadow_rel, AccessExclusiveLock);
heap_close(pg_shadow_rel);
UserAbortTransactionBlock();
elog(ERROR,
@@ -187,7 +187,7 @@ DefineUser(CreateUserStmt *stmt)
* 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.
*/
RelationUnsetLockForWrite(pg_shadow_rel);
UnlockRelation(pg_shadow_rel, AccessExclusiveLock);
heap_close(pg_shadow_rel);
if (IsTransactionBlock() && !inblock)
@@ -235,14 +235,14 @@ AlterUser(AlterUserStmt *stmt)
* dump of the pg_pwd file is done, there is not another backend doing
* the same.
*/
RelationSetLockForWrite(pg_shadow_rel);
LockRelation(pg_shadow_rel, AccessExclusiveLock);
tuple = SearchSysCacheTuple(USENAME,
PointerGetDatum(stmt->user),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
{
RelationUnsetLockForWrite(pg_shadow_rel);
UnlockRelation(pg_shadow_rel, AccessExclusiveLock);
heap_close(pg_shadow_rel);
UserAbortTransactionBlock(); /* needed? */
elog(ERROR, "alterUser: user \"%s\" does not exist", stmt->user);
@@ -288,7 +288,7 @@ AlterUser(AlterUserStmt *stmt)
UpdatePgPwdFile(sql);
RelationUnsetLockForWrite(pg_shadow_rel);
UnlockRelation(pg_shadow_rel, AccessExclusiveLock);
heap_close(pg_shadow_rel);
if (IsTransactionBlock() && !inblock)
@@ -342,14 +342,14 @@ RemoveUser(char *user)
* dump of the pg_pwd file is done, there is not another backend doing
* the same.
*/
RelationSetLockForWrite(pg_shadow_rel);
LockRelation(pg_shadow_rel, AccessExclusiveLock);
tuple = SearchSysCacheTuple(USENAME,
PointerGetDatum(user),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
{
RelationUnsetLockForWrite(pg_shadow_rel);
UnlockRelation(pg_shadow_rel, AccessExclusiveLock);
heap_close(pg_shadow_rel);
UserAbortTransactionBlock();
elog(ERROR, "removeUser: user \"%s\" does not exist", user);
@@ -422,7 +422,7 @@ RemoveUser(char *user)
UpdatePgPwdFile(sql);
RelationUnsetLockForWrite(pg_shadow_rel);
UnlockRelation(pg_shadow_rel, AccessExclusiveLock);
heap_close(pg_shadow_rel);
if (IsTransactionBlock() && !inblock)

View File

@@ -7,7 +7,7 @@
*
*
* 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)
}
/* we require the relation to be locked until the indices are cleaned */
RelationSetLockForWrite(onerel);
LockRelation(onerel, AccessExclusiveLock);
/* scan it */
vacuum_pages.vpl_num_pages = fraged_pages.vpl_num_pages = 0;
@@ -1918,7 +1918,7 @@ vc_delhilowstats(Oid relid, int attcnt, int *attnums)
if (i >= attcnt)
continue; /* don't delete it */
}
heap_delete(pgstatistic, &tuple->t_self);
heap_delete(pgstatistic, &tuple->t_self, NULL);
}
heap_endscan(scan);
@@ -1928,11 +1928,7 @@ vc_delhilowstats(Oid relid, int attcnt, int *attnums)
static void
vc_setpagelock(Relation rel, BlockNumber blkno)
{
ItemPointerData itm;
ItemPointerSet(&itm, blkno, 1);
RelationSetLockForWritePage(rel, &itm);
LockPage(rel, blkno, ExclusiveLock);
}
/*