From: Shigeru Hanada Date: Wed, 17 Nov 2010 09:45:45 +0000 (+0900) Subject: Add GetFdwRoutineByRelId(), which retrieves FdwRoutine object from X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=47403390ffe188b5f4d87b906c60cebe6229d4af;p=users%2Fhanada%2Fpostgres.git Add GetFdwRoutineByRelId(), which retrieves FdwRoutine object from oid of the foreign table directly, to avoid creating useless objects. --- diff --git a/src/backend/foreign/foreign.c b/src/backend/foreign/foreign.c index 0458a2fc48..bbf04759fc 100644 --- a/src/backend/foreign/foreign.c +++ b/src/backend/foreign/foreign.c @@ -38,7 +38,7 @@ extern Datum postgresql_fdw_validator(PG_FUNCTION_ARGS); /* - * GetForeignDataWrapper - look up the foreign-data wrapper by OID. + * GetForeignDataWrapper - look up the foreign-data wrapper by OID. */ ForeignDataWrapper * GetForeignDataWrapper(Oid fdwid) @@ -485,6 +485,10 @@ GetForeignTable(Oid relid) return ft; } +/* + * GetFdwRoutine - look up the handler of the foreign-data wrapper by OID and + * retrieve FdwRoutine. + */ FdwRoutine * GetFdwRoutine(Oid fdwhandler) { @@ -507,6 +511,62 @@ GetFdwRoutine(Oid fdwhandler) return routine; } +/* + * GetFdwRoutineByRelId - look up the handler of the foreign-data wrapper by + * OID of the foreign table and retrieve FdwRoutine. + */ +FdwRoutine * +GetFdwRoutineByRelId(Oid relid) +{ + HeapTuple tp; + Form_pg_foreign_data_wrapper fdwform; + Form_pg_foreign_server serverform; + Form_pg_foreign_table tableform; + Oid serverid; + Oid fdwid; + Oid fdwhandler; + FmgrInfo flinfo; + FunctionCallInfoData fcinfo; + Datum result; + FdwRoutine *routine; + + /* Get function 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); + + tp = SearchSysCache1(FOREIGNSERVEROID, ObjectIdGetDatum(serverid)); + if (!HeapTupleIsValid(tp)) + elog(ERROR, "cache lookup failed for foreign server %u", serverid); + serverform = (Form_pg_foreign_server) GETSTRUCT(tp); + fdwid = serverform->srvfdw; + ReleaseSysCache(tp); + + tp = SearchSysCache1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdwid)); + if (!HeapTupleIsValid(tp)) + elog(ERROR, "cache lookup failed for foreign-data wrapper %u", fdwid); + fdwform = (Form_pg_foreign_data_wrapper) GETSTRUCT(tp); + fdwhandler = fdwform->fdwhandler; + ReleaseSysCache(tp); + + /* Get FdwRoutine by invoking fdwhandler function. */ + fmgr_info(fdwhandler, &flinfo); + InitFunctionCallInfoData(fcinfo, &flinfo, 0, NULL, NULL); + result = FunctionCallInvoke(&fcinfo); + + if (fcinfo.isnull || + (routine = (FdwRoutine *) DatumGetPointer(result)) == NULL) + { + elog(ERROR, "function %u returned NULL", flinfo.fn_oid); + routine = NULL; /* keep compiler quiet */ + } + + return routine; +} + /* * Determine the relation is a foreign table. */ diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index 6a8faf8bde..bc416218f6 100644 --- a/src/backend/optimizer/path/costsize.c +++ b/src/backend/optimizer/path/costsize.c @@ -1030,9 +1030,6 @@ cost_foreignscan(ForeignPath *path, PlannerInfo *root, RelOptInfo *baserel) { RangeTblEntry *rte; - ForeignTable *table; - ForeignServer *server; - ForeignDataWrapper *wrapper; FdwRoutine *routine; /* Should only be applied to base relations */ @@ -1041,11 +1038,7 @@ cost_foreignscan(ForeignPath *path, PlannerInfo *root, /* Leave estimation of the costs to the wrapper handler */ rte = planner_rt_fetch(baserel->relid, root); - table = GetForeignTable(rte->relid); - server = GetForeignServer(table->serverid); - wrapper = GetForeignDataWrapper(server->fdwid); - routine = GetFdwRoutine(wrapper->fdwhandler); - + routine = GetFdwRoutineByRelId(rte->relid); if (routine->EstimateCosts != NULL) routine->EstimateCosts(path, root, baserel); } diff --git a/src/include/foreign/foreign.h b/src/include/foreign/foreign.h index 743a36f2e4..ef3fe9e312 100644 --- a/src/include/foreign/foreign.h +++ b/src/include/foreign/foreign.h @@ -84,6 +84,7 @@ extern ForeignDataWrapper *GetForeignDataWrapperByName(const char *name, extern Oid GetForeignDataWrapperOidByName(const char *name, bool missing_ok); extern ForeignTable *GetForeignTable(Oid relid); extern FdwRoutine *GetFdwRoutine(Oid fdwhandler); +extern FdwRoutine *GetFdwRoutineByRelId(Oid relid); extern bool IsForeignTable(Oid relid); extern Oid GetFdwValidator(Oid relid); extern List *GetGenericOptionsPerColumn(Oid relid, int2 attnum);