Commit 6c6f395a authored by Tom Lane's avatar Tom Lane

Since COPY fires triggers, it seems like a good idea for it to use

a frozen (copied) snapshot too.  Move execMain's snapshot copying code
out into a subroutine in case we find other places that need it.
parent 26fcd25c
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.155 2002/05/21 22:05:54 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.156 2002/05/21 22:59:00 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -447,6 +447,7 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, ...@@ -447,6 +447,7 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp,
bool *isvarlena; bool *isvarlena;
int16 fld_size; int16 fld_size;
char *string; char *string;
Snapshot mySnapshot;
if (oids && !rel->rd_rel->relhasoids) if (oids && !rel->rd_rel->relhasoids)
elog(ERROR, "COPY: table %s does not have OIDs", elog(ERROR, "COPY: table %s does not have OIDs",
...@@ -494,7 +495,9 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, ...@@ -494,7 +495,9 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp,
CopySendData(&tmp, sizeof(int32), fp); CopySendData(&tmp, sizeof(int32), fp);
} }
scandesc = heap_beginscan(rel, QuerySnapshot, 0, NULL); mySnapshot = CopyQuerySnapshot();
scandesc = heap_beginscan(rel, mySnapshot, 0, NULL);
while ((tuple = heap_getnext(scandesc, ForwardScanDirection)) != NULL) while ((tuple = heap_getnext(scandesc, ForwardScanDirection)) != NULL)
{ {
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.162 2002/05/21 22:05:55 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.163 2002/05/21 22:59:01 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -101,7 +101,6 @@ TupleDesc ...@@ -101,7 +101,6 @@ TupleDesc
ExecutorStart(QueryDesc *queryDesc, EState *estate) ExecutorStart(QueryDesc *queryDesc, EState *estate)
{ {
TupleDesc result; TupleDesc result;
Snapshot es_snapshot;
/* sanity checks */ /* sanity checks */
Assert(queryDesc != NULL); Assert(queryDesc != NULL);
...@@ -121,22 +120,7 @@ ExecutorStart(QueryDesc *queryDesc, EState *estate) ...@@ -121,22 +120,7 @@ ExecutorStart(QueryDesc *queryDesc, EState *estate)
* for the life of this query, even if it outlives the current command * for the life of this query, even if it outlives the current command
* and current snapshot. * and current snapshot.
*/ */
if (QuerySnapshot == NULL) /* should be set already, but... */ estate->es_snapshot = CopyQuerySnapshot();
SetQuerySnapshot();
es_snapshot = (Snapshot) palloc(sizeof(SnapshotData));
memcpy(es_snapshot, QuerySnapshot, sizeof(SnapshotData));
if (es_snapshot->xcnt > 0)
{
es_snapshot->xip = (TransactionId *)
palloc(es_snapshot->xcnt * sizeof(TransactionId));
memcpy(es_snapshot->xip, QuerySnapshot->xip,
es_snapshot->xcnt * sizeof(TransactionId));
}
else
es_snapshot->xip = NULL;
estate->es_snapshot = es_snapshot;
/* /*
* Initialize the plan * Initialize the plan
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.51 2002/05/21 22:05:55 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.52 2002/05/21 22:59:01 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -963,6 +963,40 @@ SetQuerySnapshot(void) ...@@ -963,6 +963,40 @@ SetQuerySnapshot(void)
Assert(QuerySnapshot != NULL); Assert(QuerySnapshot != NULL);
} }
/*
* CopyQuerySnapshot
* Copy the current query snapshot.
*
* Copying the snapshot is done so that a query is guaranteed to use a
* consistent snapshot for its entire execution life, even if the command
* counter is incremented or SetQuerySnapshot() is called while it runs
* (as could easily happen, due to triggers etc. executing queries).
*
* The copy is palloc'd in the current memory context.
*/
Snapshot
CopyQuerySnapshot(void)
{
Snapshot snapshot;
if (QuerySnapshot == NULL) /* should be set already, but... */
SetQuerySnapshot();
snapshot = (Snapshot) palloc(sizeof(SnapshotData));
memcpy(snapshot, QuerySnapshot, sizeof(SnapshotData));
if (snapshot->xcnt > 0)
{
snapshot->xip = (TransactionId *)
palloc(snapshot->xcnt * sizeof(TransactionId));
memcpy(snapshot->xip, QuerySnapshot->xip,
snapshot->xcnt * sizeof(TransactionId));
}
else
snapshot->xip = NULL;
return snapshot;
}
/* /*
* FreeXactSnapshot * FreeXactSnapshot
* Free snapshot(s) at end of transaction. * Free snapshot(s) at end of transaction.
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: tqual.h,v 1.39 2002/05/21 22:05:55 tgl Exp $ * $Id: tqual.h,v 1.40 2002/05/21 22:59:01 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -112,6 +112,7 @@ extern HTSV_Result HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, ...@@ -112,6 +112,7 @@ extern HTSV_Result HeapTupleSatisfiesVacuum(HeapTupleHeader tuple,
extern Snapshot GetSnapshotData(bool serializable); extern Snapshot GetSnapshotData(bool serializable);
extern void SetQuerySnapshot(void); extern void SetQuerySnapshot(void);
extern Snapshot CopyQuerySnapshot(void);
extern void FreeXactSnapshot(void); extern void FreeXactSnapshot(void);
#endif /* TQUAL_H */ #endif /* TQUAL_H */
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