From 07a601eedab7c5fa4d62055fa3efacef2f38e446 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sun, 7 Aug 2016 14:36:02 -0400
Subject: [PATCH] Avoid crashing in GetOldestSnapshot() if there are no known
 snapshots.

The sole caller expects NULL to be returned in such a case, so make
it so and document it.

Per reports from Andreas Seltenreich and Regina Obe.  This doesn't
really fix their problem, as now their RETURNING queries will say
"ERROR: no known snapshots", but in any case this function should
not dump core in a reasonably-foreseeable situation.

Report: <87vazemeda.fsf@credativ.de>
Report: <20160807051854.1427.32414@wrigleys.postgresql.org>
---
 src/backend/utils/time/snapmgr.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/src/backend/utils/time/snapmgr.c b/src/backend/utils/time/snapmgr.c
index 4bddaed33ba..1ec9f70f0ee 100644
--- a/src/backend/utils/time/snapmgr.c
+++ b/src/backend/utils/time/snapmgr.c
@@ -399,14 +399,14 @@ GetLatestSnapshot(void)
 /*
  * GetOldestSnapshot
  *
- *		Get the oldest known snapshot, as judged by the LSN.
+ *		Get the transaction's oldest known snapshot, as judged by the LSN.
+ *		Will return NULL if there are no active or registered snapshots.
  */
 Snapshot
 GetOldestSnapshot(void)
 {
 	Snapshot	OldestRegisteredSnapshot = NULL;
 	XLogRecPtr	RegisteredLSN = InvalidXLogRecPtr;
-	XLogRecPtr	ActiveLSN = InvalidXLogRecPtr;
 
 	if (!pairingheap_is_empty(&RegisteredSnapshots))
 	{
@@ -416,10 +416,12 @@ GetOldestSnapshot(void)
 	}
 
 	if (OldestActiveSnapshot != NULL)
-		ActiveLSN = OldestActiveSnapshot->as_snap->lsn;
+	{
+		XLogRecPtr	ActiveLSN = OldestActiveSnapshot->as_snap->lsn;
 
-	if (XLogRecPtrIsInvalid(RegisteredLSN) || RegisteredLSN > ActiveLSN)
-		return OldestActiveSnapshot->as_snap;
+		if (XLogRecPtrIsInvalid(RegisteredLSN) || RegisteredLSN > ActiveLSN)
+			return OldestActiveSnapshot->as_snap;
+	}
 
 	return OldestRegisteredSnapshot;
 }
-- 
GitLab