*** a/contrib/postgres_fdw/postgres_fdw.c --- b/contrib/postgres_fdw/postgres_fdw.c *************** *** 65,72 **** enum FdwScanPrivateIndex FdwScanPrivateRetrievedAttrs, /* Integer representing the desired fetch_size */ FdwScanPrivateFetchSize, - /* Oid of user mapping to be used while connecting to the foreign server */ - FdwScanPrivateUserMappingOid, /* * String describing join i.e. names of relations being joined and types --- 65,70 ---- *************** *** 1133,1142 **** postgresGetForeignPlan(PlannerInfo *root, * Build the fdw_private list that will be available to the executor. * Items in the list must match order in enum FdwScanPrivateIndex. */ ! fdw_private = list_make4(makeString(sql.data), retrieved_attrs, ! makeInteger(fpinfo->fetch_size), ! makeInteger(foreignrel->umid)); if (foreignrel->reloptkind == RELOPT_JOINREL) fdw_private = lappend(fdw_private, makeString(fpinfo->relation_name->data)); --- 1131,1139 ---- * Build the fdw_private list that will be available to the executor. * Items in the list must match order in enum FdwScanPrivateIndex. */ ! fdw_private = list_make3(makeString(sql.data), retrieved_attrs, ! makeInteger(fpinfo->fetch_size)); if (foreignrel->reloptkind == RELOPT_JOINREL) fdw_private = lappend(fdw_private, makeString(fpinfo->relation_name->data)); *************** *** 1168,1174 **** postgresBeginForeignScan(ForeignScanState *node, int eflags) --- 1165,1175 ---- ForeignScan *fsplan = (ForeignScan *) node->ss.ps.plan; EState *estate = node->ss.ps.state; PgFdwScanState *fsstate; + RangeTblEntry *rte; + Oid userid; + ForeignTable *table; UserMapping *user; + int rtindex; int numParams; int i; ListCell *lc; *************** *** 1193,1221 **** postgresBeginForeignScan(ForeignScanState *node, int eflags) * information goes stale between planning and execution, plan will be * invalidated and replanned. */ - if (fsplan->scan.scanrelid > 0) - { - ForeignTable *table; ! /* ! * Identify which user to do the remote access as. This should match ! * what ExecCheckRTEPerms() does. ! */ ! RangeTblEntry *rte = rt_fetch(fsplan->scan.scanrelid, estate->es_range_table); ! Oid userid = rte->checkAsUser ? rte->checkAsUser : GetUserId(); ! ! fsstate->rel = node->ss.ss_currentRelation; ! table = GetForeignTable(RelationGetRelid(fsstate->rel)); ! ! user = GetUserMapping(userid, table->serverid); ! } else { ! Oid umid = intVal(list_nth(fsplan->fdw_private, FdwScanPrivateUserMappingOid)); ! ! user = GetUserMappingById(umid); ! Assert(fsplan->fs_server == user->serverid); } /* * Get connection to the foreign server. Connection manager will --- 1194,1217 ---- * information goes stale between planning and execution, plan will be * invalidated and replanned. */ ! /* ! * Identify which user to do the remote access as. This should match what ! * ExecCheckRTEPerms() does. ! */ ! if (fsplan->scan.scanrelid > 0) ! rtindex = fsplan->scan.scanrelid; else { ! /* Pick the lowest-numbered one as a representative */ ! rtindex = bms_first_member(fsplan->fs_relids); } + rte = rt_fetch(rtindex, estate->es_range_table); + userid = rte->checkAsUser ? rte->checkAsUser : GetUserId(); + + /* Get info about foreign table */ + table = GetForeignTable(rte->relid); + user = GetUserMapping(userid, table->serverid); /* * Get connection to the foreign server. Connection manager will *************** *** 1252,1260 **** postgresBeginForeignScan(ForeignScanState *node, int eflags) --- 1248,1262 ---- * into local representation and error reporting during that process. */ if (fsplan->scan.scanrelid > 0) + { + fsstate->rel = node->ss.ss_currentRelation; fsstate->tupdesc = RelationGetDescr(fsstate->rel); + } else + { + fsstate->rel = NULL; fsstate->tupdesc = node->ss.ss_ScanTupleSlot->tts_tupleDescriptor; + } fsstate->attinmeta = TupleDescGetAttInMetadata(fsstate->tupdesc);