contrib/postgres_fdw/connection.c
PGconn *
GetConnection(UserMapping *user, bool will_prep_stmt)
{
	bool		found;
	ConnCacheEntry *entry;
	ConnCacheKey key;

	/* First time through, initialize connection cache hashtable */
	if (ConnectionHash == NULL)
	{
		HASHCTL		ctl;

		MemSet(&ctl, 0, sizeof(ctl));
		ctl.keysize = sizeof(ConnCacheKey);
		ctl.entrysize = sizeof(ConnCacheEntry);
		/* allocate ConnectionHash in the cache context */
		ctl.hcxt = CacheMemoryContext;
		ConnectionHash = hash_create("postgres_fdw connections", 8,
									 &ctl,
									 HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);

		/*
		 * Register some callback functions that manage connection cleanup.
		 * This should be done just once in each backend.
		 */
		RegisterXactCallback(pgfdw_xact_callback, NULL);
		RegisterSubXactCallback(pgfdw_subxact_callback, NULL);
	}

	/* Set flag that we did GetConnection during the current transaction */
	xact_got_connection = true;

	/* Create hash key for the entry.  Assume no pad bytes in key struct */
	key = user->umid;

	/*
	 * Find or create cached entry for requested connection.
	 */
	entry = hash_search(ConnectionHash, &key, HASH_ENTER, &found);
	if (!found)
	{
		/* initialize new hashtable entry (key is already filled in) */
		entry->conn = NULL;
		entry->xact_depth = 0;
		entry->have_prep_stmt = false;
		entry->have_error = false;
	}

	/*
	 * We don't check the health of cached connection here, because it would
	 * require some overhead.  Broken connection will be detected when the
	 * connection is actually used.
	 */

	/*
	 * 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
	 * will be left in a valid empty state.)
	 */
	if (entry->conn == NULL)
	{
		ForeignServer *server = GetForeignServer(user->serverid);

		entry->xact_depth = 0;	/* just to be sure */
		entry->have_prep_stmt = false;
		entry->have_error = false;
		entry->conn = connect_pg_server(server, user);

		elog(DEBUG3, "new postgres_fdw connection %p for server \"%s\" (user mapping oid %u, userid %u)",
			 entry->conn, server->servername, user->umid, user->userid);
	}

	/*
	 * Start a new transaction or subtransaction if needed.
	 */
	begin_remote_xact(entry);

	/* Remember if caller will prepare statements */
	entry->have_prep_stmt |= will_prep_stmt;

	return entry->conn;
}
/*
 * Get a PGconn which can be used to execute queries on the remote PostgreSQL
 * server with the user's authorization.  A new connection is established
 * if we don't already have a suitable one, and a transaction is opened at
 * the right subtransaction nesting depth if we didn't do that already.
 *
 * will_prep_stmt must be true if caller intends to create any prepared
 * statements.  Since those don't go away automatically at transaction end
 * (not even on error), we need this flag to cue manual cleanup.
 *
 * XXX Note that caching connections theoretically requires a mechanism to
 * detect change of FDW objects to invalidate already established connections.
 * We could manage that by watching for invalidation events on the relevant
 * syscaches.  For the moment, though, it's not clear that this would really
 * be useful and not mere pedantry.  We could not flush any active connections
 * mid-transaction anyway.
 */
Get a PGconn which can be used to execute queries on the remote PostgreSQL
server with the user's authorization.  A new connection is established
if we don't already have a suitable one, and a transaction is opened at
the right subtransaction nesting depth if we didn't do that already.

will_prep_stmt must be true if caller intends to create any prepared
statements.  Since those don't go away automatically at transaction end
(not even on error), we need this flag to cue manual cleanup.

XXX Note that caching connections theoretically requires a mechanism to
detect change of FDW objects to invalidate already established connections.
We could manage that by watching for invalidation events on the relevant
syscaches.  For the moment, though, it's not clear that this would really
be useful and not mere pedantry.  We could not flush any active connections
mid-transaction anyway.
Get a PGconn which can be used to execute queries on the remote PostgreSQL server with the user ' s authorization . A new connection is established if we don ' t already have a suitable one and a transaction is opened at the right subtransaction nesting depth if we didn ' t do that already . will_prep_stmt must be true if caller intends to create any prepared statements . Since those don ' t go away automatically at transaction end ( not even on error ) we need this flag to cue manual cleanup . XXX Note that caching connections theoretically requires a mechanism to detect change of FDW objects to invalidate already established connections . We could manage that by watching for invalidation events on the relevant syscaches . For the moment though it ' s not clear that this would really be useful and not mere pedantry . We could not flush any active connections mid - transaction anyway .
PGconn *
GetConnection(UserMapping *user, bool will_prep_stmt)
{
	bool		found;
	ConnCacheEntry *entry;
	ConnCacheKey key;
	if (ConnectionHash == NULL)
	{
		HASHCTL		ctl;
		MemSet(&ctl, 0, sizeof(ctl));
		ctl.keysize = sizeof(ConnCacheKey);
		ctl.entrysize = sizeof(ConnCacheEntry);
		ctl.hcxt = CacheMemoryContext;
		ConnectionHash = hash_create("postgres_fdw connections", 8,
									 &ctl,
									 HASH_ELEM | HASH_BLOBS | HASH_CONTEXT);
		RegisterXactCallback(pgfdw_xact_callback, NULL);
		RegisterSubXactCallback(pgfdw_subxact_callback, NULL);
	}
	xact_got_connection = true;
	key = user->umid;
	entry = hash_search(ConnectionHash, &key, HASH_ENTER, &found);
	if (!found)
	{
		entry->conn = NULL;
		entry->xact_depth = 0;
		entry->have_prep_stmt = false;
		entry->have_error = false;
	}
	if (entry->conn == NULL)
	{
		ForeignServer *server = GetForeignServer(user->serverid);
		entry->xact_depth = 0;	
		entry->have_prep_stmt = false;
		entry->have_error = false;
		entry->conn = connect_pg_server(server, user);
		elog(DEBUG3, "new postgres_fdw connection %p for server \"%s\" (user mapping oid %u, userid %u)",
			 entry->conn, server->servername, user->umid, user->userid);
	}
	begin_remote_xact(entry);
	entry->have_prep_stmt |= will_prep_stmt;
	return entry->conn;
}
PGconn * GetConnection ( UserMapping * user , bool will_prep_stmt ) { bool found ; ConnCacheEntry * entry ; ConnCacheKey key ; if ( ConnectionHash == NULL ) { HASHCTL ctl ; MemSet ( & ctl , 0 , sizeof ( ctl ) ) ; ctl . keysize = sizeof ( ConnCacheKey ) ; ctl . entrysize = sizeof ( ConnCacheEntry ) ; ctl . hcxt = CacheMemoryContext ; ConnectionHash = hash_create ( " " , 8 , & ctl , HASH_ELEM | HASH_BLOBS | HASH_CONTEXT ) ; RegisterXactCallback ( pgfdw_xact_callback , NULL ) ; RegisterSubXactCallback ( pgfdw_subxact_callback , NULL ) ; } xact_got_connection = true ; key = user -> umid ; entry = hash_search ( ConnectionHash , & key , HASH_ENTER , & found ) ; if ( ! found ) { entry -> conn = NULL ; entry -> xact_depth = 0 ; entry -> have_prep_stmt = false ; entry -> have_error = false ; } if ( entry -> conn == NULL ) { ForeignServer * server = GetForeignServer ( user -> serverid ) ; entry -> xact_depth = 0 ; entry -> have_prep_stmt = false ; entry -> have_error = false ; entry -> conn = connect_pg_server ( server , user ) ; elog ( DEBUG3 , " \" \" " , entry -> conn , server -> servername , user -> umid , user -> userid ) ; } begin_remote_xact ( entry ) ; entry -> have_prep_stmt |= will_prep_stmt ; return entry -> conn ; }
Get a PGconn which can be used to execute queries on the remote PostgreSQL
 server with the user's authorization.
Get a PGconn which can be used to execute queries on the remote PostgreSQL server with the user ' s authorization .
/* First time through, initialize connection cache hashtable */ /* allocate ConnectionHash in the cache context */ /*
		 * Register some callback functions that manage connection cleanup.
		 * This should be done just once in each backend.
		 */ /* Set flag that we did GetConnection during the current transaction */ /* Create hash key for the entry.  Assume no pad bytes in key struct */ /*
	 * Find or create cached entry for requested connection.
	 */ /* initialize new hashtable entry (key is already filled in) */ /*
	 * We don't check the health of cached connection here, because it would
	 * require some overhead.  Broken connection will be detected when the
	 * connection is actually used.
	 */ /*
	 * 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
	 * will be left in a valid empty state.)
	 */ /* just to be sure */ /*
	 * Start a new transaction or subtransaction if needed.
	 */ /* Remember if caller will prepare statements */