summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2002-05-21 22:59:01 +0000
committerTom Lane2002-05-21 22:59:01 +0000
commit6c6f395a8aca8a9525d62cbf46fbafd130bdb9e5 (patch)
tree3441e3fff093efdb62b2ef19cac4371fe248c241
parent26fcd25c57cd56cd42f1cec73ede1198d1ca941b (diff)
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.
-rw-r--r--src/backend/commands/copy.c7
-rw-r--r--src/backend/executor/execMain.c20
-rw-r--r--src/backend/utils/time/tqual.c36
-rw-r--r--src/include/utils/tqual.h3
4 files changed, 44 insertions, 22 deletions
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 83ca5b32c54..16c23d320ee 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -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)
{
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index a8c776bab2c..29687a54baa 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -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
diff --git a/src/backend/utils/time/tqual.c b/src/backend/utils/time/tqual.c
index 58534159f7a..582ec28183e 100644
--- a/src/backend/utils/time/tqual.c
+++ b/src/backend/utils/time/tqual.c
@@ -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 $
*
*-------------------------------------------------------------------------
*/
@@ -964,6 +964,40 @@ SetQuerySnapshot(void)
}
/*
+ * 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.
*/
diff --git a/src/include/utils/tqual.h b/src/include/utils/tqual.h
index f5f03ea01af..3ddceff5f8d 100644
--- a/src/include/utils/tqual.h
+++ b/src/include/utils/tqual.h
@@ -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 */