diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index 189f290..3d1b4fa 100644
--- a/contrib/postgres_fdw/connection.c
+++ b/contrib/postgres_fdw/connection.c
@@ -47,6 +47,7 @@ typedef struct ConnCacheEntry
 								 * one level of subxact open, etc */
 	bool		have_prep_stmt; /* have we prepared any stmts in this xact? */
 	bool		have_error;		/* have any subxacts aborted in this xact? */
+	bool		to_be_disconnected;
 } ConnCacheEntry;
 
 /*
@@ -137,6 +138,7 @@ GetConnection(UserMapping *user, bool will_prep_stmt)
 		entry->xact_depth = 0;
 		entry->have_prep_stmt = false;
 		entry->have_error = false;
+		entry->to_be_disconnected = false;
 	}
 
 	/*
@@ -145,6 +147,14 @@ GetConnection(UserMapping *user, bool will_prep_stmt)
 	 * connection is actually used.
 	 */
 
+	if (entry->conn != NULL &&
+		entry->to_be_disconnected && entry->xact_depth == 0)
+	{
+		elog(LOG, "disconnected");
+		PQfinish(entry->conn);
+		entry->conn = NULL;
+		entry->to_be_disconnected = false;
+	}
 	/*
 	 * If cache entry doesn't have a connection, we have to establish a new
 	 * connection.  (If connect_pg_server throws an error, the cache entry
@@ -270,6 +280,26 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
 	return conn;
 }
 
+void
+reserve_pg_disconnect(Oid umid)
+{
+	bool		found;
+	ConnCacheEntry *entry;
+	ConnCacheKey key;
+
+	if (ConnectionHash == NULL)
+		return;
+
+	/* Find existing connectionentry */
+	key = umid;
+	entry = hash_search(ConnectionHash, &key, HASH_ENTER, &found);
+
+	if (!found || entry->conn == NULL)
+		return;
+
+	entry->to_be_disconnected = true;
+}
+
 /*
  * For non-superusers, insist that the connstr specify a password.  This
  * prevents a password from being picked up from .pgpass, a service file,
diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c
index 4fbbde1..7777875 100644
--- a/contrib/postgres_fdw/postgres_fdw.c
+++ b/contrib/postgres_fdw/postgres_fdw.c
@@ -16,6 +16,9 @@
 
 #include "access/htup_details.h"
 #include "access/sysattr.h"
+#include "catalog/pg_foreign_server.h"
+#include "catalog/pg_user_mapping.h"
+#include "catalog/objectaccess.h"
 #include "commands/defrem.h"
 #include "commands/explain.h"
 #include "commands/vacuum.h"
@@ -33,7 +36,9 @@
 #include "optimizer/tlist.h"
 #include "parser/parsetree.h"
 #include "utils/builtins.h"
+#include "utils/fmgroids.h"
 #include "utils/guc.h"
+#include "utils/syscache.h"
 #include "utils/lsyscache.h"
 #include "utils/memutils.h"
 #include "utils/rel.h"
@@ -407,7 +412,16 @@ static List *get_useful_pathkeys_for_relation(PlannerInfo *root,
 static List *get_useful_ecs_for_relation(PlannerInfo *root, RelOptInfo *rel);
 static void add_paths_with_pathkeys_for_rel(PlannerInfo *root, RelOptInfo *rel,
 								Path *epq_path);
+static void postgresObjectAccessHook(ObjectAccessType access,
+													 Oid classId,
+													 Oid objectId,
+													 int subId,
+													 void *arg);
+									 
+static object_access_hook_type previous_object_access_hook;
 
+void		_PG_init(void);
+void		_PG_fini(void);
 
 /*
  * Foreign-data wrapper handler function: return a struct with pointers
@@ -460,6 +474,19 @@ postgres_fdw_handler(PG_FUNCTION_ARGS)
 	PG_RETURN_POINTER(routine);
 }
 
+void
+_PG_init(void)
+{
+	previous_object_access_hook = object_access_hook;
+	object_access_hook = postgresObjectAccessHook;
+}
+
+void
+_PG_fini(void)
+{
+	object_access_hook = previous_object_access_hook;
+}
+
 /*
  * postgresGetForeignRelSize
  *		Estimate # of rows and width of the result of the scan
@@ -4492,3 +4519,43 @@ find_em_expr_for_rel(EquivalenceClass *ec, RelOptInfo *rel)
 	/* We didn't find any suitable equivalence class expression */
 	return NULL;
 }
+
+static void
+postgresObjectAccessHook(ObjectAccessType access,
+						 Oid classId,
+						 Oid objectId,
+						 int subId,
+						 void *arg)
+{
+	if (access == OAT_POST_ALTER)
+	{
+		if (classId == ForeignServerRelationId)
+		{
+			Relation umrel;
+			ScanKeyData skey;
+			SysScanDesc scan;
+			HeapTuple umtup;
+
+			umrel = heap_open(UserMappingRelationId, AccessShareLock);
+			ScanKeyInit(&skey,
+						Anum_pg_user_mapping_umserver,
+						BTEqualStrategyNumber, F_OIDEQ,
+						ObjectIdGetDatum(objectId));
+			scan = systable_beginscan(umrel, InvalidOid, false,
+									  NULL, 1, &skey);
+			while(HeapTupleIsValid(umtup = systable_getnext(scan)))
+				reserve_pg_disconnect(HeapTupleGetOid(umtup));
+
+			systable_endscan(scan);
+			heap_close(umrel, AccessShareLock);
+		}
+		if (classId == UserMappingRelationId)
+		{
+			reserve_pg_disconnect(objectId);
+		}
+	}
+		
+
+	if (previous_object_access_hook)
+		previous_object_access_hook(access, classId, objectId, subId, arg);
+}
diff --git a/contrib/postgres_fdw/postgres_fdw.h b/contrib/postgres_fdw/postgres_fdw.h
index 3a11d99..7e8ea31 100644
--- a/contrib/postgres_fdw/postgres_fdw.h
+++ b/contrib/postgres_fdw/postgres_fdw.h
@@ -100,6 +100,7 @@ extern void reset_transmission_modes(int nestlevel);
 
 /* in connection.c */
 extern PGconn *GetConnection(UserMapping *user, bool will_prep_stmt);
+extern void reserve_pg_disconnect(Oid umid);
 extern void ReleaseConnection(PGconn *conn);
 extern unsigned int GetCursorNumber(PGconn *conn);
 extern unsigned int GetPrepStmtNumber(PGconn *conn);
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index 804bab2..ebae253 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -1312,6 +1312,9 @@ AlterUserMapping(AlterUserMappingStmt *stmt)
 
 	ObjectAddressSet(address, UserMappingRelationId, umId);
 
+	/* Post alter hook for new user mapping */
+	InvokeObjectPostAlterHook(UserMappingRelationId, umId, 0);
+
 	heap_freetuple(tp);
 
 	heap_close(rel, RowExclusiveLock);
