aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils')
-rw-r--r--src/backend/utils/mmgr/portalmem.c4
-rw-r--r--src/backend/utils/time/snapmgr.c17
2 files changed, 20 insertions, 1 deletions
diff --git a/src/backend/utils/mmgr/portalmem.c b/src/backend/utils/mmgr/portalmem.c
index 6ac0b2666af..e7a45423532 100644
--- a/src/backend/utils/mmgr/portalmem.c
+++ b/src/backend/utils/mmgr/portalmem.c
@@ -210,6 +210,7 @@ CreatePortal(const char *name, bool allowDup, bool dupSilent)
portal->cleanup = PortalCleanup;
portal->createSubid = GetCurrentSubTransactionId();
portal->activeSubid = portal->createSubid;
+ portal->createLevel = GetCurrentTransactionNestLevel();
portal->strategy = PORTAL_MULTI_QUERY;
portal->cursorOptions = CURSOR_OPT_NO_SCROLL;
portal->atStart = true;
@@ -655,6 +656,7 @@ HoldPortal(Portal portal)
*/
portal->createSubid = InvalidSubTransactionId;
portal->activeSubid = InvalidSubTransactionId;
+ portal->createLevel = 0;
}
/*
@@ -938,6 +940,7 @@ PortalErrorCleanup(void)
void
AtSubCommit_Portals(SubTransactionId mySubid,
SubTransactionId parentSubid,
+ int parentLevel,
ResourceOwner parentXactOwner)
{
HASH_SEQ_STATUS status;
@@ -952,6 +955,7 @@ AtSubCommit_Portals(SubTransactionId mySubid,
if (portal->createSubid == mySubid)
{
portal->createSubid = parentSubid;
+ portal->createLevel = parentLevel;
if (portal->resowner)
ResourceOwnerNewParent(portal->resowner, parentXactOwner);
}
diff --git a/src/backend/utils/time/snapmgr.c b/src/backend/utils/time/snapmgr.c
index edf59efc29d..f4401060643 100644
--- a/src/backend/utils/time/snapmgr.c
+++ b/src/backend/utils/time/snapmgr.c
@@ -732,9 +732,24 @@ FreeSnapshot(Snapshot snapshot)
void
PushActiveSnapshot(Snapshot snap)
{
+ PushActiveSnapshotWithLevel(snap, GetCurrentTransactionNestLevel());
+}
+
+/*
+ * PushActiveSnapshotWithLevel
+ * Set the given snapshot as the current active snapshot
+ *
+ * Same as PushActiveSnapshot except that caller can specify the
+ * transaction nesting level that "owns" the snapshot. This level
+ * must not be deeper than the current top of the snapshot stack.
+ */
+void
+PushActiveSnapshotWithLevel(Snapshot snap, int snap_level)
+{
ActiveSnapshotElt *newactive;
Assert(snap != InvalidSnapshot);
+ Assert(ActiveSnapshot == NULL || snap_level >= ActiveSnapshot->as_level);
newactive = MemoryContextAlloc(TopTransactionContext, sizeof(ActiveSnapshotElt));
@@ -748,7 +763,7 @@ PushActiveSnapshot(Snapshot snap)
newactive->as_snap = snap;
newactive->as_next = ActiveSnapshot;
- newactive->as_level = GetCurrentTransactionNestLevel();
+ newactive->as_level = snap_level;
newactive->as_snap->active_count++;