From d4594067b29ab1414e9741a7e6abd91daf078201 Mon Sep 17 00:00:00 2001
From: Bharath Rupireddy <bharath.rupireddy@enterprisedb.com>
Date: Mon, 22 Jun 2020 10:07:53 +0530
Subject: [PATCH v1] enable_connectioncache GUC for postgres_fdw connection
 caching

postgres_fdw connection caching - cause remote sessions linger
till the local session exit.
---
 contrib/postgres_fdw/connection.c             |  3 ++-
 src/backend/utils/hash/dynahash.c             | 11 +++++++++++
 src/backend/utils/misc/guc.c                  | 15 +++++++++++++++
 src/backend/utils/misc/postgresql.conf.sample |  2 +-
 src/include/utils/hsearch.h                   |  4 ++++
 5 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index 52d1fe3563..de994f678b 100644
--- a/contrib/postgres_fdw/connection.c
+++ b/contrib/postgres_fdw/connection.c
@@ -869,7 +869,8 @@ pgfdw_xact_callback(XactEvent event, void *arg)
 		 */
 		if (PQstatus(entry->conn) != CONNECTION_OK ||
 			PQtransactionStatus(entry->conn) != PQTRANS_IDLE ||
-			entry->changing_xact_state)
+			entry->changing_xact_state ||
+			scan.enableconncache == false)
 		{
 			elog(DEBUG3, "discarding connection %p", entry->conn);
 			disconnect_pg_server(entry);
diff --git a/src/backend/utils/hash/dynahash.c b/src/backend/utils/hash/dynahash.c
index 2688e27726..a5448f4af4 100644
--- a/src/backend/utils/hash/dynahash.c
+++ b/src/backend/utils/hash/dynahash.c
@@ -276,6 +276,9 @@ static bool has_seq_scans(HTAB *hashp);
  */
 static MemoryContext CurrentDynaHashCxt = NULL;
 
+/* parameter for enabling fdw connection hashing */
+bool	enable_connectioncache = true;
+
 static void *
 DynaHashAlloc(Size size)
 {
@@ -1383,6 +1386,14 @@ hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
 	status->hashp = hashp;
 	status->curBucket = 0;
 	status->curEntry = NULL;
+	status->enableconncache = true;
+
+	/* see if the cache was for postgres_fdw connections and
+	   user chose to disable connection caching*/
+	if ((strcmp(hashp->tabname,"postgres_fdw connections") == 0) &&
+		!enable_connectioncache)
+		status->enableconncache = false;
+
 	if (!hashp->frozen)
 		register_seq_scan(hashp);
 }
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 75fc6f11d6..f7a57415fc 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -127,6 +127,7 @@ extern char *temp_tablespaces;
 extern bool ignore_checksum_failure;
 extern bool ignore_invalid_pages;
 extern bool synchronize_seqscans;
+extern bool	enable_connectioncache;
 
 #ifdef TRACE_SYNCSCAN
 extern bool trace_syncscan;
@@ -2041,6 +2042,20 @@ static struct config_bool ConfigureNamesBool[] =
 		NULL, NULL, NULL
 	},
 
+	{
+		{"enable_connectioncache", PGC_USERSET, RESOURCES_MEM,
+			gettext_noop("Enables postgres_fdw connection caching."),
+			gettext_noop("The postgres_fdw connections are cached and "
+						 "reused within the same session by default. "
+						 "Setting this parameter to false, discards the "
+						 "remote connection at the end of the transaction."),
+			GUC_EXPLAIN
+		},
+		&enable_connectioncache,
+		true,
+		NULL, NULL, NULL
+	},
+
 	/* End-of-list marker */
 	{
 		{NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL, NULL
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 3a25287a39..1a55177df2 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -184,7 +184,7 @@
 #old_snapshot_threshold = -1		# 1min-60d; -1 disables; 0 is immediate
 					# (change requires restart)
 #backend_flush_after = 0		# measured in pages, 0 disables
-
+#enable_connectioncache = on
 
 #------------------------------------------------------------------------------
 # WRITE-AHEAD LOG
diff --git a/src/include/utils/hsearch.h b/src/include/utils/hsearch.h
index f1deb9beab..77546a7c16 100644
--- a/src/include/utils/hsearch.h
+++ b/src/include/utils/hsearch.h
@@ -114,6 +114,10 @@ typedef struct
 	HTAB	   *hashp;
 	uint32		curBucket;		/* index of current bucket */
 	HASHELEMENT *curEntry;		/* current entry in bucket */
+	/* if true, fdw connections in a session are cached, else
+	   discarded at the end of every remote transaction.
+	*/
+	bool        enableconncache;
 } HASH_SEQ_STATUS;
 
 /*
-- 
2.25.1

