* 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
| 122 | * with the PGconn. |
| 123 | */ |
| 124 | PGconn * |
| 125 | GetConnection(UserMapping *user, bool will_prep_stmt, PgFdwConnState **state) |
| 126 | { |
| 127 | bool found; |
| 128 | bool retry = false; |
| 129 | ConnCacheEntry *entry; |
| 130 | ConnCacheKey key; |
| 131 | MemoryContext ccxt = CurrentMemoryContext; |
| 132 | |
| 133 | /* First time through, initialize connection cache hashtable */ |
| 134 | if (ConnectionHash == NULL) |
| 135 | { |
| 136 | HASHCTL ctl; |
| 137 | |
| 138 | ctl.keysize = sizeof(ConnCacheKey); |
| 139 | ctl.entrysize = sizeof(ConnCacheEntry); |
| 140 | ConnectionHash = hash_create("postgres_fdw connections", 8, |
| 141 | &ctl, |
| 142 | HASH_ELEM | HASH_BLOBS); |
| 143 | |
| 144 | /* |
| 145 | * Register some callback functions that manage connection cleanup. |
| 146 | * This should be done just once in each backend. |
| 147 | */ |
| 148 | RegisterXactCallback(pgfdw_xact_callback, NULL); |
| 149 | RegisterSubXactCallback(pgfdw_subxact_callback, NULL); |
| 150 | CacheRegisterSyscacheCallback(FOREIGNSERVEROID, |
| 151 | pgfdw_inval_callback, (Datum) 0); |
| 152 | CacheRegisterSyscacheCallback(USERMAPPINGOID, |
| 153 | pgfdw_inval_callback, (Datum) 0); |
| 154 | } |
| 155 | |
| 156 | /* Set flag that we did GetConnection during the current transaction */ |
| 157 | xact_got_connection = true; |
| 158 | |
| 159 | /* Create hash key for the entry. Assume no pad bytes in key struct */ |
| 160 | key = user->umid; |
| 161 | |
| 162 | /* |
| 163 | * Find or create cached entry for requested connection. |
| 164 | */ |
| 165 | entry = hash_search(ConnectionHash, &key, HASH_ENTER, &found); |
| 166 | if (!found) |
| 167 | { |
| 168 | /* |
| 169 | * We need only clear "conn" here; remaining fields will be filled |
| 170 | * later when "conn" is set. |
| 171 | */ |
| 172 | entry->conn = NULL; |
| 173 | } |
| 174 | |
| 175 | /* Reject further use of connections which failed abort cleanup. */ |
| 176 | pgfdw_reject_incomplete_xact_state_change(entry); |
| 177 | |
| 178 | /* |
| 179 | * If the connection needs to be remade due to invalidation, disconnect as |
| 180 | * soon as we're out of all transactions. |
| 181 | */ |
no test coverage detected