Fix very old bug which made tuples changed/inserted by a commnd

visible to command itself (so we had multiple update of updated tuples,
etc).
This commit is contained in:
Vadim B. Mikheev 1997-08-29 09:05:25 +00:00
parent e06099c607
commit 3152996ffb
3 changed files with 63 additions and 11 deletions

View File

@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.12 1997/08/19 21:30:19 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.13 1997/08/29 09:02:11 vadim Exp $
* *
* NOTES * NOTES
* Transaction aborts can now occur two ways: * Transaction aborts can now occur two ways:
@ -377,6 +377,22 @@ GetCurrentCommandId()
return s->commandId; return s->commandId;
} }
CommandId
GetScanCommandId()
{
TransactionState s = CurrentTransactionState;
/* ----------------
* if the transaction system is disabled, we return
* the special "disabled" command id.
* ----------------
*/
if (s->state == TRANS_DISABLED)
return (CommandId) DisabledCommandId;
return s->scanCommandId;
}
/* -------------------------------- /* --------------------------------
* GetCurrentTransactionStartTime * GetCurrentTransactionStartTime
@ -432,6 +448,18 @@ CommandIdIsCurrentCommandId(CommandId cid)
(cid == s->commandId) ? true : false; (cid == s->commandId) ? true : false;
} }
bool
CommandIdGEScanCommandId(CommandId cid)
{
TransactionState s = CurrentTransactionState;
if (AMI_OVERRIDE)
return false;
return
(cid >= s->scanCommandId) ? true : false;
}
/* -------------------------------- /* --------------------------------
* ClearCommandIdCounterOverflowFlag * ClearCommandIdCounterOverflowFlag
@ -458,11 +486,22 @@ CommandCounterIncrement()
elog(WARN, "You may only have 65535 commands per transaction"); elog(WARN, "You may only have 65535 commands per transaction");
} }
CurrentTransactionStateData.scanCommandId =
CurrentTransactionStateData.commandId;
/* make cache changes visible to me */ /* make cache changes visible to me */
AtCommit_Cache(); AtCommit_Cache();
AtStart_Cache(); AtStart_Cache();
} }
void
SetScanCommandId (CommandId savedId)
{
CurrentTransactionStateData.scanCommandId = savedId;
}
/* ---------------------------------------------------------------- /* ----------------------------------------------------------------
* initialization stuff * initialization stuff
* ---------------------------------------------------------------- * ----------------------------------------------------------------
@ -757,6 +796,7 @@ StartTransaction()
* ---------------- * ----------------
*/ */
s->commandId = FirstCommandId; s->commandId = FirstCommandId;
s->scanCommandId = FirstCommandId;
s->startTime = GetCurrentAbsoluteTime(); s->startTime = GetCurrentAbsoluteTime();
/* ---------------- /* ----------------

View File

@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.3 1997/08/19 21:36:12 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.4 1997/08/29 09:04:54 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -580,6 +580,13 @@ HeapTupleSatisfiesItself(HeapTuple 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
@ -615,13 +622,13 @@ HeapTupleSatisfiesNow(HeapTuple tuple)
if (!AbsoluteTimeIsBackwardCompatiblyValid(tuple->t_tmin)) { if (!AbsoluteTimeIsBackwardCompatiblyValid(tuple->t_tmin)) {
if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmin) if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmin)
&& CommandIdIsCurrentCommandId(tuple->t_cmin)) { && CommandIdGEScanCommandId(tuple->t_cmin)) {
return (false); return (false);
} }
if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmin) if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmin)
&& !CommandIdIsCurrentCommandId(tuple->t_cmin)) { && !CommandIdGEScanCommandId(tuple->t_cmin)) {
if (!TransactionIdIsValid((TransactionId)tuple->t_xmax)) { if (!TransactionIdIsValid((TransactionId)tuple->t_xmax)) {
return (true); return (true);
@ -629,7 +636,7 @@ HeapTupleSatisfiesNow(HeapTuple tuple)
Assert(TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmax)); Assert(TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmax));
if (CommandIdIsCurrentCommandId(tuple->t_cmax)) { if (CommandIdGEScanCommandId(tuple->t_cmax)) {
return (true); return (true);
} }
} }
@ -813,13 +820,13 @@ HeapTupleSatisfiesUpperUnboundedInternalTimeQual(HeapTuple tuple,
if (!AbsoluteTimeIsBackwardCompatiblyValid(tuple->t_tmin)) { if (!AbsoluteTimeIsBackwardCompatiblyValid(tuple->t_tmin)) {
if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmin) && if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmin) &&
CommandIdIsCurrentCommandId(tuple->t_cmin)) { CommandIdGEScanCommandId(tuple->t_cmin)) {
return (false); return (false);
} }
if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmin) && if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmin) &&
!CommandIdIsCurrentCommandId(tuple->t_cmin)) { !CommandIdGEScanCommandId(tuple->t_cmin)) {
if (!TransactionIdIsValid((TransactionId)tuple->t_xmax)) { if (!TransactionIdIsValid((TransactionId)tuple->t_xmax)) {
return (true); return (true);
@ -827,7 +834,7 @@ HeapTupleSatisfiesUpperUnboundedInternalTimeQual(HeapTuple tuple,
Assert(TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmax)); Assert(TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmax));
return ((bool) !CommandIdIsCurrentCommandId(tuple->t_cmax)); return ((bool) !CommandIdGEScanCommandId(tuple->t_cmax));
} }
if (!TransactionIdDidCommit((TransactionId)tuple->t_xmin)) { if (!TransactionIdDidCommit((TransactionId)tuple->t_xmin)) {
@ -849,7 +856,8 @@ HeapTupleSatisfiesUpperUnboundedInternalTimeQual(HeapTuple tuple,
} }
if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmax)) { if (TransactionIdIsCurrentTransactionId((TransactionId)tuple->t_xmax)) {
return (CommandIdIsCurrentCommandId(tuple->t_cmin)); return (CommandIdGEScanCommandId(tuple->t_cmin));
/* it looks like error ^^^^ */
} }
if (!TransactionIdDidCommit((TransactionId)tuple->t_xmax)) { if (!TransactionIdDidCommit((TransactionId)tuple->t_xmax)) {

View File

@ -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.5 1997/08/19 21:37:40 momjian Exp $ * $Id: xact.h,v 1.6 1997/08/29 09:05:25 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -22,6 +22,7 @@
typedef struct TransactionStateData { typedef struct TransactionStateData {
TransactionId transactionIdData; TransactionId transactionIdData;
CommandId commandId; CommandId commandId;
CommandId scanCommandId;
AbsoluteTime startTime; AbsoluteTime startTime;
int state; int state;
int blockState; int blockState;
@ -63,9 +64,12 @@ extern bool IsAbortedTransactionBlockState(void);
extern void OverrideTransactionSystem(bool flag); extern void OverrideTransactionSystem(bool flag);
extern TransactionId GetCurrentTransactionId(void); extern TransactionId GetCurrentTransactionId(void);
extern CommandId GetCurrentCommandId(void); extern CommandId GetCurrentCommandId(void);
extern CommandId GetScanCommandId(void);
extern void SetScanCommandId(CommandId);
extern AbsoluteTime GetCurrentTransactionStartTime(void); extern AbsoluteTime GetCurrentTransactionStartTime(void);
extern bool TransactionIdIsCurrentTransactionId(TransactionId xid); extern bool TransactionIdIsCurrentTransactionId(TransactionId xid);
extern bool CommandIdIsCurrentCommandId(CommandId cid); extern bool CommandIdIsCurrentCommandId(CommandId cid);
extern bool CommandIdGEScanCommandId(CommandId cid);
extern void CommandCounterIncrement(void); extern void CommandCounterIncrement(void);
extern void InitializeTransactionSystem(void); extern void InitializeTransactionSystem(void);
extern bool CurrentXactInProgress(void); extern bool CurrentXactInProgress(void);