*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
bool *isvarlena;
int16 fld_size;
char *string;
+ Snapshot mySnapshot;
if (oids && !rel->rd_rel->relhasoids)
elog(ERROR, "COPY: table %s does not have OIDs",
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)
{
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
ExecutorStart(QueryDesc *queryDesc, EState *estate)
{
TupleDesc result;
- Snapshot es_snapshot;
/* sanity checks */
Assert(queryDesc != NULL);
* 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
* 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 $
*
*-------------------------------------------------------------------------
*/
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.
* 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 $
*
*-------------------------------------------------------------------------
*/
extern Snapshot GetSnapshotData(bool serializable);
extern void SetQuerySnapshot(void);
+extern Snapshot CopyQuerySnapshot(void);
extern void FreeXactSnapshot(void);
#endif /* TQUAL_H */