postgres_fdw: Save foreign server OID in connection cache entry.
authorFujii Masao
Fri, 15 Jan 2021 01:30:19 +0000 (10:30 +0900)
committerFujii Masao
Fri, 15 Jan 2021 01:30:19 +0000 (10:30 +0900)
The foreign server OID stored in the connection cache entry is used as
a lookup key to directly get the server name.

Previously since the connection cache entry did not have the server OID,
postgres_fdw had to get the server OID at first from user mapping before
getting the server name. So if the corresponding user mapping was dropped,
postgres_fdw could raise the error "cache lookup failed for user mapping"
while looking up user mapping and fail to get the server name even though
the server had not been dropped yet.

Author: Bharath Rupireddy
Reviewed-by: Fujii Masao
Discussion: https://postgr.es/m/CALj2ACVRZPUB7ZwqLn-6DY8C_UmPs6084gSpHA92YBv++1AJXA@mail.gmail.com

contrib/postgres_fdw/connection.c

index 266f66cc62ce1e03697fdc63f47a6cd2620aca48..eaedfea9f248e36bbbd774864c55471102bcf1ca 100644 (file)
@@ -57,6 +57,7 @@ typedef struct ConnCacheEntry
    bool        have_error;     /* have any subxacts aborted in this xact? */
    bool        changing_xact_state;    /* xact state change in process */
    bool        invalidated;    /* true if reconnect is pending */
+   Oid         serverid;       /* foreign server OID used to get server name */
    uint32      server_hashvalue;   /* hash value of foreign server OID */
    uint32      mapping_hashvalue;  /* hash value of user mapping OID */
 } ConnCacheEntry;
@@ -273,6 +274,7 @@ make_new_connection(ConnCacheEntry *entry, UserMapping *user)
    entry->have_error = false;
    entry->changing_xact_state = false;
    entry->invalidated = false;
+   entry->serverid = server->serverid;
    entry->server_hashvalue =
        GetSysCacheHashValue1(FOREIGNSERVEROID,
                              ObjectIdGetDatum(server->serverid));
@@ -1138,8 +1140,6 @@ pgfdw_inval_callback(Datum arg, int cacheid, uint32 hashvalue)
 static void
 pgfdw_reject_incomplete_xact_state_change(ConnCacheEntry *entry)
 {
-   HeapTuple   tup;
-   Form_pg_user_mapping umform;
    ForeignServer *server;
 
    /* nothing to do for inactive entries and entries of sane state */
@@ -1150,13 +1150,7 @@ pgfdw_reject_incomplete_xact_state_change(ConnCacheEntry *entry)
    disconnect_pg_server(entry);
 
    /* find server name to be shown in the message below */
-   tup = SearchSysCache1(USERMAPPINGOID,
-                         ObjectIdGetDatum(entry->key));
-   if (!HeapTupleIsValid(tup))
-       elog(ERROR, "cache lookup failed for user mapping %u", entry->key);
-   umform = (Form_pg_user_mapping) GETSTRUCT(tup);
-   server = GetForeignServer(umform->umserver);
-   ReleaseSysCache(tup);
+   server = GetForeignServer(entry->serverid);
 
    ereport(ERROR,
            (errcode(ERRCODE_CONNECTION_EXCEPTION),