summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/util/pathnode.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/util/pathnode.c')
-rw-r--r--src/backend/optimizer/util/pathnode.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index d1010af6622..1158f7715bc 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -17,6 +17,7 @@
#include <math.h>
#include "catalog/pg_operator.h"
+#include "foreign/fdwapi.h"
#include "miscadmin.h"
#include "nodes/nodeFuncs.h"
#include "optimizer/clauses.h"
@@ -1420,6 +1421,41 @@ create_worktablescan_path(PlannerInfo *root, RelOptInfo *rel)
}
/*
+ * create_foreignscan_path
+ * Creates a path corresponding to a scan of a foreign table,
+ * returning the pathnode.
+ */
+ForeignPath *
+create_foreignscan_path(PlannerInfo *root, RelOptInfo *rel)
+{
+ ForeignPath *pathnode = makeNode(ForeignPath);
+ RangeTblEntry *rte;
+ FdwRoutine *fdwroutine;
+ FdwPlan *fdwplan;
+
+ pathnode->path.pathtype = T_ForeignScan;
+ pathnode->path.parent = rel;
+ pathnode->path.pathkeys = NIL; /* result is always unordered */
+
+ /* Get FDW's callback info */
+ rte = planner_rt_fetch(rel->relid, root);
+ fdwroutine = GetFdwRoutineByRelId(rte->relid);
+
+ /* Let the FDW do its planning */
+ fdwplan = fdwroutine->PlanForeignScan(rte->relid, root, rel);
+ if (fdwplan == NULL || !IsA(fdwplan, FdwPlan))
+ elog(ERROR, "foreign-data wrapper PlanForeignScan function for relation %u did not return an FdwPlan struct",
+ rte->relid);
+ pathnode->fdwplan = fdwplan;
+
+ /* use costs estimated by FDW */
+ pathnode->path.startup_cost = fdwplan->startup_cost;
+ pathnode->path.total_cost = fdwplan->total_cost;
+
+ return pathnode;
+}
+
+/*
* create_nestloop_path
* Creates a pathnode corresponding to a nestloop join between two
* relations.