From 5b06d83e000132eca5a3173e96651ddf4531cff6 Mon Sep 17 00:00:00 2001
From: Jehan-Guillaume de Rorthais <jgdr@dalibo.com>
Date: Thu, 25 Jul 2019 19:36:40 +0200
Subject: [PATCH] Add function pg_current_timeline

---
 src/backend/access/transam/xlog.c      | 26 ++++++++++++++++++++++++++
 src/backend/access/transam/xlogfuncs.c | 17 +++++++++++++++++
 src/include/access/xlog.h              |  1 +
 src/include/catalog/pg_proc.dat        |  6 ++++++
 4 files changed, 50 insertions(+)

diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index da3d250986..9da876c0ac 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -12243,3 +12243,29 @@ XLogRequestWalReceiverReply(void)
 {
 	doRequestWalReceiverReply = true;
 }
+
+/*
+ * Returns current active timeline.
+ * During production, returns ThisTimeLineID.
+ * During standby, returns the timeline of the latest record flushed to XLOG.
+ */
+TimeLineID
+GetCurrentTimeLine(void)
+{
+	TimeLineID	localTimeLineID;
+	bool		localRecoveryInProgress;
+
+	SpinLockAcquire(&XLogCtl->info_lck);
+
+	localTimeLineID = XLogCtl->ThisTimeLineID;
+	localRecoveryInProgress = XLogCtl->SharedRecoveryInProgress;
+
+	SpinLockRelease(&XLogCtl->info_lck);
+
+	if (localRecoveryInProgress) {
+		 GetWalRcvWriteRecPtr(NULL, &localTimeLineID);
+		 return localTimeLineID;
+	}
+
+	return localTimeLineID;
+}
diff --git a/src/backend/access/transam/xlogfuncs.c b/src/backend/access/transam/xlogfuncs.c
index b35043bf71..c1cb9e8819 100644
--- a/src/backend/access/transam/xlogfuncs.c
+++ b/src/backend/access/transam/xlogfuncs.c
@@ -776,3 +776,20 @@ pg_promote(PG_FUNCTION_ARGS)
 			(errmsg("server did not promote within %d seconds", wait_seconds)));
 	PG_RETURN_BOOL(false);
 }
+
+/*
+ * Returns the current timeline
+ */
+Datum
+pg_current_timeline(PG_FUNCTION_ARGS)
+{
+	TimeLineID currentTL = GetCurrentTimeLine();
+
+	/*
+	 * we have no information about the timeline if the walreceiver
+	 * is disabled or hasn't streamed anything yet,
+	 */
+	if (!currentTL) PG_RETURN_NULL();
+
+	PG_RETURN_INT32(currentTL);
+}
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index d519252aad..f0502c0b41 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -313,6 +313,7 @@ extern XLogRecPtr GetInsertRecPtr(void);
 extern XLogRecPtr GetFlushRecPtr(void);
 extern XLogRecPtr GetLastImportantRecPtr(void);
 extern void RemovePromoteSignalFiles(void);
+extern TimeLineID GetCurrentTimeLine(void);
 
 extern bool CheckPromoteSignal(void);
 extern void WakeupRecovery(void);
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 0902dce5f1..42cd7c3486 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -6006,6 +6006,12 @@
 { oid => '2851', descr => 'wal filename, given a wal location',
   proname => 'pg_walfile_name', prorettype => 'text', proargtypes => 'pg_lsn',
   prosrc => 'pg_walfile_name' },
+{ oid => '3434',
+  descr => 'return the current timeline',
+  proname => 'pg_current_timeline', prorettype => 'int4',
+  proargtypes => '', proallargtypes => '{int4}',
+  proargmodes => '{o}', proargnames => '{timeline}',
+  prosrc => 'pg_current_timeline' },
 
 { oid => '3165', descr => 'difference in bytes, given two wal locations',
   proname => 'pg_wal_lsn_diff', prorettype => 'numeric',
-- 
2.20.1

