]> granicus.if.org Git - postgresql/commitdiff
Since COPY fires triggers, it seems like a good idea for it to use
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 21 May 2002 22:59:01 +0000 (22:59 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 21 May 2002 22:59:01 +0000 (22:59 +0000)
a frozen (copied) snapshot too.  Move execMain's snapshot copying code
out into a subroutine in case we find other places that need it.

src/backend/commands/copy.c
src/backend/executor/execMain.c
src/backend/utils/time/tqual.c
src/include/utils/tqual.h

index 83ca5b32c5439fea5ed981060caeb0aed3360df5..16c23d320ee4e3d98ec559c1dd56a309cb39e081 100644 (file)
@@ -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)
        {
index a8c776bab2c4a89b145ef3721933b3851fd34463..29687a54baa2a9744e1a3f78b2c7bf02256142c6 100644 (file)
@@ -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
index 58534159f7a95d17e408354e4f7a53725fc20f24..582ec28183ee058c68227f45fb317648ada89203 100644 (file)
@@ -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.
index f5f03ea01af737c978ee3708cd1b1ac665fb2bfd..3ddceff5f8db1d4f24c1563cb22fb70031ac90ef 100644 (file)
@@ -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 */