src/backend/executor/nodeForeignscan.c | 2 +- src/backend/foreign/foreign.c | 50 +++++++++++++++++++++------------ src/backend/nodes/copyfuncs.c | 2 +- src/backend/nodes/outfuncs.c | 2 +- src/backend/optimizer/plan/createplan.c | 2 +- src/backend/optimizer/util/plancat.c | 4 +-- src/backend/optimizer/util/relnode.c | 12 ++++---- src/include/foreign/fdwapi.h | 3 +- src/include/nodes/plannodes.h | 2 +- src/include/nodes/relation.h | 4 +-- 10 files changed, 49 insertions(+), 34 deletions(-) diff --git a/src/backend/executor/nodeForeignscan.c b/src/backend/executor/nodeForeignscan.c index fa553ac..17f7fb8 100644 --- a/src/backend/executor/nodeForeignscan.c +++ b/src/backend/executor/nodeForeignscan.c @@ -169,7 +169,7 @@ ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags) /* * Acquire function pointers from the FDW's handler, and init fdw_state. */ - fdwroutine = GetFdwRoutine(node->fdw_handler); + fdwroutine = GetFdwRoutineByServer(node->fdw_server); scanstate->fdwroutine = fdwroutine; scanstate->fdw_state = NULL; diff --git a/src/backend/foreign/foreign.c b/src/backend/foreign/foreign.c index cdbd550..ea293ca 100644 --- a/src/backend/foreign/foreign.c +++ b/src/backend/foreign/foreign.c @@ -281,6 +281,27 @@ GetForeignColumnOptions(Oid relid, AttrNumber attnum) return options; } +/* + * GetFdwRoutineByRelId - looks up Oid of the foreign server for the + * given foreign table. + */ +Oid +GetFdwServerByRelId(Oid relid) +{ + HeapTuple tp; + Form_pg_foreign_table tableform; + Oid serverid; + + /* Get server OID for the foreign table. */ + tp = SearchSysCache1(FOREIGNTABLEREL, ObjectIdGetDatum(relid)); + if (!HeapTupleIsValid(tp)) + elog(ERROR, "cache lookup failed for foreign table %u", relid); + tableform = (Form_pg_foreign_table) GETSTRUCT(tp); + serverid = tableform->ftserver; + ReleaseSysCache(tp); + + return serverid; +} /* * GetFdwRoutine - call the specified foreign-data wrapper handler routine @@ -302,30 +323,19 @@ GetFdwRoutine(Oid fdwhandler) return routine; } - /* - * GetFdwHandlerByRelId - look up the handler of the foreign-data wrapper - * for the given foreign table + * GetFdwRoutineByServer - look up the handler of the foreign-data wrapper + * for the given foreign server, and retrieve its FdwRoutine struct. */ -Oid -GetFdwHandlerByRelId(Oid relid) +FdwRoutine * +GetFdwRoutineByServer(Oid serverid) { HeapTuple tp; Form_pg_foreign_data_wrapper fdwform; Form_pg_foreign_server serverform; - Form_pg_foreign_table tableform; - Oid serverid; Oid fdwid; Oid fdwhandler; - /* Get server OID for the foreign table. */ - tp = SearchSysCache1(FOREIGNTABLEREL, ObjectIdGetDatum(relid)); - if (!HeapTupleIsValid(tp)) - elog(ERROR, "cache lookup failed for foreign table %u", relid); - tableform = (Form_pg_foreign_table) GETSTRUCT(tp); - serverid = tableform->ftserver; - ReleaseSysCache(tp); - /* Get foreign-data wrapper OID for the server. */ tp = SearchSysCache1(FOREIGNSERVEROID, ObjectIdGetDatum(serverid)); if (!HeapTupleIsValid(tp)) @@ -350,7 +360,8 @@ GetFdwHandlerByRelId(Oid relid) ReleaseSysCache(tp); - return fdwhandler; + /* And finally, call the handler function. */ + return GetFdwRoutine(fdwhandler); } /* @@ -360,9 +371,12 @@ GetFdwHandlerByRelId(Oid relid) FdwRoutine * GetFdwRoutineByRelId(Oid relid) { - Oid fdwhandler = GetFdwHandlerByRelId(relid); + Oid serverid; - return GetFdwRoutine(fdwhandler); + /* Get server OID for the foreign table. */ + serverid = GetFdwServerByRelId(relid); + /* Then retrieve its FdwRoutine struct */ + return GetFdwRoutineByServer(serverid); } /* diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 805045d..aa05590 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -592,7 +592,7 @@ _copyForeignScan(const ForeignScan *from) /* * copy remainder of node */ - COPY_SCALAR_FIELD(fdw_handler); + COPY_SCALAR_FIELD(fdw_server); COPY_NODE_FIELD(fdw_exprs); COPY_NODE_FIELD(fdw_ps_tlist); COPY_NODE_FIELD(fdw_private); diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index f9f948e..5a94c5e 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -558,7 +558,7 @@ _outForeignScan(StringInfo str, const ForeignScan *node) _outScanInfo(str, (const Scan *) node); - WRITE_OID_FIELD(fdw_handler); + WRITE_OID_FIELD(fdw_server); WRITE_NODE_FIELD(fdw_exprs); WRITE_NODE_FIELD(fdw_ps_tlist); WRITE_NODE_FIELD(fdw_private); diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index eeb2a41..a3f23ad 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -2024,7 +2024,7 @@ create_foreignscan_plan(PlannerInfo *root, ForeignPath *best_path, copy_path_costsize(&scan_plan->scan.plan, &best_path->path); /* Track FDW server-id; no need to make FDW do this */ - scan_plan->fdw_handler = rel->fdw_handler; + scan_plan->fdw_server = rel->fdw_server; /* * Replace any outer-relation variables with nestloop params in the qual diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 068ab39..d81736c 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -380,12 +380,12 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, /* Grab the fdwroutine info using the relcache, while we have it */ if (relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE) { - rel->fdw_handler = GetFdwHandlerByRelId(RelationGetRelid(relation)); + rel->fdw_server = GetFdwServerByRelId(RelationGetRelid(relation)); rel->fdwroutine = GetFdwRoutineForRelation(relation, true); } else { - rel->fdw_handler = InvalidOid; + rel->fdw_server = InvalidOid; rel->fdwroutine = NULL; } heap_close(relation, NoLock); diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c index 5623566..e6a5349 100644 --- a/src/backend/optimizer/util/relnode.c +++ b/src/backend/optimizer/util/relnode.c @@ -123,7 +123,7 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptKind reloptkind) rel->subroot = NULL; rel->subplan_params = NIL; rel->fdwroutine = NULL; - rel->fdw_handler = InvalidOid; + rel->fdw_server = InvalidOid; rel->fdw_private = NULL; rel->baserestrictinfo = NIL; rel->baserestrictcost.startup = 0; @@ -432,12 +432,12 @@ build_join_rel(PlannerInfo *root, * Set FDW handler and routine if both outer and inner relation * are managed by same FDW driver. */ - if (OidIsValid(outer_rel->fdw_handler) && - OidIsValid(inner_rel->fdw_handler) && - outer_rel->fdw_handler == inner_rel->fdw_handler) + if (OidIsValid(outer_rel->fdw_server) && + OidIsValid(inner_rel->fdw_server) && + outer_rel->fdw_server == inner_rel->fdw_server) { - joinrel->fdw_handler = outer_rel->fdw_handler; - joinrel->fdwroutine = GetFdwRoutine(joinrel->fdw_handler); + joinrel->fdw_server = outer_rel->fdw_server; + joinrel->fdwroutine = GetFdwRoutineByServer(joinrel->fdw_server); } /* diff --git a/src/include/foreign/fdwapi.h b/src/include/foreign/fdwapi.h index c683d92..ff91d0f 100644 --- a/src/include/foreign/fdwapi.h +++ b/src/include/foreign/fdwapi.h @@ -168,8 +168,9 @@ typedef struct FdwRoutine /* Functions in foreign/foreign.c */ -extern Oid GetFdwHandlerByRelId(Oid relid); +extern Oid GetFdwServerByRelId(Oid relid); extern FdwRoutine *GetFdwRoutine(Oid fdwhandler); +extern FdwRoutine *GetFdwRoutineByServer(Oid server_id); extern FdwRoutine *GetFdwRoutineByRelId(Oid relid); extern FdwRoutine *GetFdwRoutineForRelation(Relation relation, bool makecopy); extern bool IsImportableForeignTable(const char *tablename, diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h index baeba2d..bd23d24 100644 --- a/src/include/nodes/plannodes.h +++ b/src/include/nodes/plannodes.h @@ -484,7 +484,7 @@ typedef struct WorkTableScan typedef struct ForeignScan { Scan scan; - Oid fdw_handler; /* OID of FDW handler */ + Oid fdw_server; /* OID of FDW server */ List *fdw_exprs; /* expressions that FDW may evaluate */ List *fdw_ps_tlist; /* tlist, if replacing a join */ List *fdw_private; /* private data for FDW */ diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index 1713d29..e0ca04f 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/relation.h @@ -366,7 +366,7 @@ typedef struct PlannerInfo * subroot - PlannerInfo for subquery (NULL if it's not a subquery) * subplan_params - list of PlannerParamItems to be passed to subquery * fdwroutine - function hooks for FDW, if foreign table (else NULL) - * fdw_handler - OID of FDW handler, if foreign table (else InvalidOid) + * fdw_server - OID of FDW server, if foreign table (else InvalidOid) * fdw_private - private state for FDW, if foreign table (else NULL) * * Note: for a subquery, tuples, subplan, subroot are not set immediately @@ -462,7 +462,7 @@ typedef struct RelOptInfo List *subplan_params; /* if subquery */ /* use "struct FdwRoutine" to avoid including fdwapi.h here */ struct FdwRoutine *fdwroutine; /* if foreign table */ - Oid fdw_handler; /* if foreign table */ + Oid fdw_server; /* if foreign table */ void *fdw_private; /* if foreign table */ /* used by various scans and joins: */