Skip to content

Commit 6c6f395

Browse files
committed
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.
1 parent 26fcd25 commit 6c6f395

File tree

4 files changed

+44
-22
lines changed

4 files changed

+44
-22
lines changed

src/backend/commands/copy.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.155 2002/05/21 22:05:54 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.156 2002/05/21 22:59:00 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -447,6 +447,7 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp,
447447
bool *isvarlena;
448448
int16 fld_size;
449449
char *string;
450+
Snapshot mySnapshot;
450451

451452
if (oids && !rel->rd_rel->relhasoids)
452453
elog(ERROR, "COPY: table %s does not have OIDs",
@@ -494,7 +495,9 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp,
494495
CopySendData(&tmp, sizeof(int32), fp);
495496
}
496497

497-
scandesc = heap_beginscan(rel, QuerySnapshot, 0, NULL);
498+
mySnapshot = CopyQuerySnapshot();
499+
500+
scandesc = heap_beginscan(rel, mySnapshot, 0, NULL);
498501

499502
while ((tuple = heap_getnext(scandesc, ForwardScanDirection)) != NULL)
500503
{

src/backend/executor/execMain.c

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
*
2828
*
2929
* IDENTIFICATION
30-
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.162 2002/05/21 22:05:55 tgl Exp $
30+
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.163 2002/05/21 22:59:01 tgl Exp $
3131
*
3232
*-------------------------------------------------------------------------
3333
*/
@@ -101,7 +101,6 @@ TupleDesc
101101
ExecutorStart(QueryDesc *queryDesc, EState *estate)
102102
{
103103
TupleDesc result;
104-
Snapshot es_snapshot;
105104

106105
/* sanity checks */
107106
Assert(queryDesc != NULL);
@@ -121,22 +120,7 @@ ExecutorStart(QueryDesc *queryDesc, EState *estate)
121120
* for the life of this query, even if it outlives the current command
122121
* and current snapshot.
123122
*/
124-
if (QuerySnapshot == NULL) /* should be set already, but... */
125-
SetQuerySnapshot();
126-
127-
es_snapshot = (Snapshot) palloc(sizeof(SnapshotData));
128-
memcpy(es_snapshot, QuerySnapshot, sizeof(SnapshotData));
129-
if (es_snapshot->xcnt > 0)
130-
{
131-
es_snapshot->xip = (TransactionId *)
132-
palloc(es_snapshot->xcnt * sizeof(TransactionId));
133-
memcpy(es_snapshot->xip, QuerySnapshot->xip,
134-
es_snapshot->xcnt * sizeof(TransactionId));
135-
}
136-
else
137-
es_snapshot->xip = NULL;
138-
139-
estate->es_snapshot = es_snapshot;
123+
estate->es_snapshot = CopyQuerySnapshot();
140124

141125
/*
142126
* Initialize the plan

src/backend/utils/time/tqual.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
* Portions Copyright (c) 1994, Regents of the University of California
1717
*
1818
* IDENTIFICATION
19-
* $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.51 2002/05/21 22:05:55 tgl Exp $
19+
* $Header: /cvsroot/pgsql/src/backend/utils/time/tqual.c,v 1.52 2002/05/21 22:59:01 tgl Exp $
2020
*
2121
*-------------------------------------------------------------------------
2222
*/
@@ -963,6 +963,40 @@ SetQuerySnapshot(void)
963963
Assert(QuerySnapshot != NULL);
964964
}
965965

966+
/*
967+
* CopyQuerySnapshot
968+
* Copy the current query snapshot.
969+
*
970+
* Copying the snapshot is done so that a query is guaranteed to use a
971+
* consistent snapshot for its entire execution life, even if the command
972+
* counter is incremented or SetQuerySnapshot() is called while it runs
973+
* (as could easily happen, due to triggers etc. executing queries).
974+
*
975+
* The copy is palloc'd in the current memory context.
976+
*/
977+
Snapshot
978+
CopyQuerySnapshot(void)
979+
{
980+
Snapshot snapshot;
981+
982+
if (QuerySnapshot == NULL) /* should be set already, but... */
983+
SetQuerySnapshot();
984+
985+
snapshot = (Snapshot) palloc(sizeof(SnapshotData));
986+
memcpy(snapshot, QuerySnapshot, sizeof(SnapshotData));
987+
if (snapshot->xcnt > 0)
988+
{
989+
snapshot->xip = (TransactionId *)
990+
palloc(snapshot->xcnt * sizeof(TransactionId));
991+
memcpy(snapshot->xip, QuerySnapshot->xip,
992+
snapshot->xcnt * sizeof(TransactionId));
993+
}
994+
else
995+
snapshot->xip = NULL;
996+
997+
return snapshot;
998+
}
999+
9661000
/*
9671001
* FreeXactSnapshot
9681002
* Free snapshot(s) at end of transaction.

src/include/utils/tqual.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
99
* Portions Copyright (c) 1994, Regents of the University of California
1010
*
11-
* $Id: tqual.h,v 1.39 2002/05/21 22:05:55 tgl Exp $
11+
* $Id: tqual.h,v 1.40 2002/05/21 22:59:01 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -112,6 +112,7 @@ extern HTSV_Result HeapTupleSatisfiesVacuum(HeapTupleHeader tuple,
112112

113113
extern Snapshot GetSnapshotData(bool serializable);
114114
extern void SetQuerySnapshot(void);
115+
extern Snapshot CopyQuerySnapshot(void);
115116
extern void FreeXactSnapshot(void);
116117

117118
#endif /* TQUAL_H */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy