aboutsummaryrefslogtreecommitdiff
path: root/contrib/postgres_fdw
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/postgres_fdw')
-rw-r--r--contrib/postgres_fdw/connection.c27
-rw-r--r--contrib/postgres_fdw/postgres_fdw.c28
-rw-r--r--contrib/postgres_fdw/postgres_fdw.h3
3 files changed, 24 insertions, 34 deletions
diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index 0c6c3cee307..6e664b0213a 100644
--- a/contrib/postgres_fdw/connection.c
+++ b/contrib/postgres_fdw/connection.c
@@ -24,9 +24,11 @@
/*
* Connection cache hash table entry
*
- * The lookup key in this hash table is the foreign server OID plus the user
- * mapping OID. (We use just one connection per user per foreign server,
- * so that we can ensure all scans use the same snapshot during a query.)
+ * The lookup key in this hash table is the user mapping OID. We use just one
+ * connection per user mapping ID, which ensures that all the scans use the
+ * same snapshot during a query. Using the user mapping OID rather than
+ * the foreign server OID + user OID avoids creating multiple connections when
+ * the public user mapping applies to all user OIDs.
*
* The "conn" pointer can be NULL if we don't currently have a live connection.
* When we do have a connection, xact_depth tracks the current depth of
@@ -35,11 +37,7 @@
* ourselves, so that rolling back a subtransaction will kill the right
* queries and not the wrong ones.
*/
-typedef struct ConnCacheKey
-{
- Oid serverid; /* OID of foreign server */
- Oid userid; /* OID of local user whose mapping we use */
-} ConnCacheKey;
+typedef Oid ConnCacheKey;
typedef struct ConnCacheEntry
{
@@ -94,8 +92,7 @@ static void pgfdw_subxact_callback(SubXactEvent event,
* mid-transaction anyway.
*/
PGconn *
-GetConnection(ForeignServer *server, UserMapping *user,
- bool will_prep_stmt)
+GetConnection(UserMapping *user, bool will_prep_stmt)
{
bool found;
ConnCacheEntry *entry;
@@ -127,8 +124,7 @@ GetConnection(ForeignServer *server, UserMapping *user,
xact_got_connection = true;
/* Create hash key for the entry. Assume no pad bytes in key struct */
- key.serverid = server->serverid;
- key.userid = user->userid;
+ key = user->umid;
/*
* Find or create cached entry for requested connection.
@@ -156,12 +152,15 @@ GetConnection(ForeignServer *server, UserMapping *user,
*/
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\"",
- entry->conn, server->servername);
+
+ elog(DEBUG3, "new postgres_fdw connection %p for server \"%s\ (user mapping oid %d, userid %d)",
+ entry->conn, server->servername, user->umid, user->userid);
}
/*
diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c
index 374faf5a25a..a237e152c02 100644
--- a/contrib/postgres_fdw/postgres_fdw.c
+++ b/contrib/postgres_fdw/postgres_fdw.c
@@ -1101,7 +1101,6 @@ postgresBeginForeignScan(ForeignScanState *node, int eflags)
RangeTblEntry *rte;
Oid userid;
ForeignTable *table;
- ForeignServer *server;
UserMapping *user;
int numParams;
int i;
@@ -1129,14 +1128,13 @@ postgresBeginForeignScan(ForeignScanState *node, int eflags)
/* Get info about foreign table. */
fsstate->rel = node->ss.ss_currentRelation;
table = GetForeignTable(RelationGetRelid(fsstate->rel));
- server = GetForeignServer(table->serverid);
- user = GetUserMapping(userid, server->serverid);
+ user = GetUserMapping(userid, table->serverid);
/*
* Get connection to the foreign server. Connection manager will
* establish new connection if necessary.
*/
- fsstate->conn = GetConnection(server, user, false);
+ fsstate->conn = GetConnection(user, false);
/* Assign a unique ID for my cursor */
fsstate->cursor_number = GetCursorNumber(fsstate->conn);
@@ -1503,7 +1501,6 @@ postgresBeginForeignModify(ModifyTableState *mtstate,
RangeTblEntry *rte;
Oid userid;
ForeignTable *table;
- ForeignServer *server;
UserMapping *user;
AttrNumber n_params;
Oid typefnoid;
@@ -1530,11 +1527,10 @@ postgresBeginForeignModify(ModifyTableState *mtstate,
/* Get info about foreign table. */
table = GetForeignTable(RelationGetRelid(rel));
- server = GetForeignServer(table->serverid);
- user = GetUserMapping(userid, server->serverid);
+ user = GetUserMapping(userid, table->serverid);
/* Open connection; report that we'll create a prepared statement. */
- fmstate->conn = GetConnection(server, user, true);
+ fmstate->conn = GetConnection(user, true);
fmstate->p_name = NULL; /* prepared statement not made yet */
/* Deconstruct fdw_private data. */
@@ -1988,7 +1984,7 @@ estimate_path_cost_size(PlannerInfo *root,
appendOrderByClause(&sql, root, baserel, pathkeys);
/* Get the remote estimate */
- conn = GetConnection(fpinfo->server, fpinfo->user, false);
+ conn = GetConnection(fpinfo->user, false);
get_remote_estimate(sql.data, conn, &rows, &width,
&startup_cost, &total_cost);
ReleaseConnection(conn);
@@ -2544,7 +2540,6 @@ postgresAnalyzeForeignTable(Relation relation,
BlockNumber *totalpages)
{
ForeignTable *table;
- ForeignServer *server;
UserMapping *user;
PGconn *conn;
StringInfoData sql;
@@ -2565,9 +2560,8 @@ postgresAnalyzeForeignTable(Relation relation,
* owner, even if the ANALYZE was started by some other user.
*/
table = GetForeignTable(RelationGetRelid(relation));
- server = GetForeignServer(table->serverid);
- user = GetUserMapping(relation->rd_rel->relowner, server->serverid);
- conn = GetConnection(server, user, false);
+ user = GetUserMapping(relation->rd_rel->relowner, table->serverid);
+ conn = GetConnection(user, false);
/*
* Construct command to get page count for relation.
@@ -2626,7 +2620,6 @@ postgresAcquireSampleRowsFunc(Relation relation, int elevel,
{
PgFdwAnalyzeState astate;
ForeignTable *table;
- ForeignServer *server;
UserMapping *user;
PGconn *conn;
unsigned int cursor_number;
@@ -2657,9 +2650,8 @@ postgresAcquireSampleRowsFunc(Relation relation, int elevel,
* owner, even if the ANALYZE was started by some other user.
*/
table = GetForeignTable(RelationGetRelid(relation));
- server = GetForeignServer(table->serverid);
- user = GetUserMapping(relation->rd_rel->relowner, server->serverid);
- conn = GetConnection(server, user, false);
+ user = GetUserMapping(relation->rd_rel->relowner, table->serverid);
+ conn = GetConnection(user, false);
/*
* Construct cursor that retrieves whole rows from remote.
@@ -2860,7 +2852,7 @@ postgresImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid)
*/
server = GetForeignServer(serverOid);
mapping = GetUserMapping(GetUserId(), server->serverid);
- conn = GetConnection(server, mapping, false);
+ conn = GetConnection(mapping, false);
/* Don't attempt to import collation if remote server hasn't got it */
if (PQserverVersion(conn) < 90100)
diff --git a/contrib/postgres_fdw/postgres_fdw.h b/contrib/postgres_fdw/postgres_fdw.h
index 85535360475..59e9f60c04b 100644
--- a/contrib/postgres_fdw/postgres_fdw.h
+++ b/contrib/postgres_fdw/postgres_fdw.h
@@ -60,8 +60,7 @@ extern int set_transmission_modes(void);
extern void reset_transmission_modes(int nestlevel);
/* in connection.c */
-extern PGconn *GetConnection(ForeignServer *server, UserMapping *user,
- bool will_prep_stmt);
+extern PGconn *GetConnection(UserMapping *user, bool will_prep_stmt);
extern void ReleaseConnection(PGconn *conn);
extern unsigned int GetCursorNumber(PGconn *conn);
extern unsigned int GetPrepStmtNumber(PGconn *conn);