提交 6c6f395a 编写于 作者: T 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.
上级 26fcd25c
......@@ -7,7 +7,7 @@
*
*
* 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,
bool *isvarlena;
int16 fld_size;
char *string;
Snapshot mySnapshot;
if (oids && !rel->rd_rel->relhasoids)
elog(ERROR, "COPY: table %s does not have OIDs",
......@@ -494,7 +495,9 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *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)
{
......
......@@ -27,7 +27,7 @@
*
*
* 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
ExecutorStart(QueryDesc *queryDesc, EState *estate)
{
TupleDesc result;
Snapshot es_snapshot;
/* sanity checks */
Assert(queryDesc != NULL);
......@@ -121,22 +120,7 @@ ExecutorStart(QueryDesc *queryDesc, EState *estate)
* for the life of this query, even if it outlives the current command
* and current snapshot.
*/
if (QuerySnapshot == NULL) /* should be set already, but... */
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;
estate->es_snapshot = CopyQuerySnapshot();
/*
* Initialize the plan
......
......@@ -16,7 +16,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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)
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
* Free snapshot(s) at end of transaction.
......
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* 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,
extern Snapshot GetSnapshotData(bool serializable);
extern void SetQuerySnapshot(void);
extern Snapshot CopyQuerySnapshot(void);
extern void FreeXactSnapshot(void);
#endif /* TQUAL_H */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册